Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
U
uniset2
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
UniSet project repositories
uniset2
Commits
2f800c5f
Commit
2f800c5f
authored
Jun 29, 2016
by
Pavel Vainerman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(DBServer_PGSQL): буфер переделан на vector, добавил немного описания.
parent
cddcc629
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
61 additions
and
26 deletions
+61
-26
TODO
TODO
+6
-0
libuniset2.spec
conf/libuniset2.spec
+1
-1
DBServer_PostgreSQL.cc
extensions/DBServer-PostgreSQL/DBServer_PostgreSQL.cc
+28
-18
DBServer_PostgreSQL.h
extensions/DBServer-PostgreSQL/DBServer_PostgreSQL.h
+12
-4
PostgreSQLInterface.cc
extensions/DBServer-PostgreSQL/PostgreSQLInterface.cc
+11
-1
PostgreSQLInterface.h
extensions/DBServer-PostgreSQL/PostgreSQLInterface.h
+2
-1
test.cc
extensions/DBServer-PostgreSQL/test.cc
+1
-1
No files found.
TODO
View file @
2f800c5f
...
...
@@ -69,6 +69,7 @@ Version 2.5
- совместимость между 64bit и 32bit - для этого нужно отказаться от использования сырого long и перейти либо на int32_t либо CORBA::Long.
- timeout_t getSharedMemoryReadyTimeout()!
libev
=======
...
...
@@ -76,9 +77,12 @@ libev
- UniSetActivator (обработка сигналов и возможно вынести сюда DefaultEventLoop) (на подумать)
SM: подумать насчёт асинхронности публикации событий и посылки уведомления (setValue/push) через очередь..
// worker-ы рассылающие сообщения, очередь заданий, конфигурирование количества worker-ов, основной поток ждёт если нет свободных.
SM: Подумать насчёт применения https://github.com/efficient/libcuckoo
DB: Сделать регулируемый буфер на INSERT-ы БД, чтобы поберечь винт (DBServer_PGSQL, DBServer_MySQL...) // по времени или по количеству
version 3
=========
- подумать нужен ли нам где-то ZeroMQ (zerorpc) (вместо omniORB?)
...
...
@@ -98,3 +102,5 @@ UResolver (или ObjectRepository) позволяющего манипулир
- вместо commoncpp,libxml2,DebugStream и т.п. перейти всё-таки на boost?
- подумать возможно стоит переходить на lockfree-библиотеку libcds..(актуально для многопроцессорных систем)
- Ввести namespace uniset:: ust:: uns:: ?
conf/libuniset2.spec
View file @
2f800c5f
...
...
@@ -84,7 +84,7 @@ There are set of base components to construct this kind of systems:
* base interfaces for your implementation of control algorithms.
* algorithms for the discrete and analog input/output based on COMEDI interface.
* IPC mechanism based on CORBA (omniORB).
* logging system based on MySQL
database
.
* logging system based on MySQL
,SQLite,PostgreSQL databases
.
* Web interface to display logging and statistic information.
* utilities for system's configuration based on XML.
...
...
extensions/DBServer-PostgreSQL/DBServer_PostgreSQL.cc
View file @
2f800c5f
...
...
@@ -203,13 +203,13 @@ void DBServer_PostgreSQL::flushInsertBuffer()
// Чистим заданное число
size_t
delnum
=
lroundf
(
ibufSize
*
ibufOverflowCleanFactor
);
InsertBuffer
::
iterator
end
=
ibuf
.
end
();
InsertBuffer
::
iterator
beg
=
ibuf
.
end
();
auto
end
=
ibuf
.
end
();
auto
beg
=
ibuf
.
end
();
// Удаляем последние (новые)
if
(
lastRemove
)
{
std
::
advance
(
end
,
-
delnum
);
std
::
advance
(
beg
,
-
delnum
);
}
else
{
...
...
@@ -220,12 +220,18 @@ void DBServer_PostgreSQL::flushInsertBuffer()
}
ibuf
.
erase
(
beg
,
end
);
ibufSize
-=
delnum
;
if
(
ibufSize
<
0
)
ibufSize
=
0
;
dbwarn
<<
myname
<<
"(flushInsertBuffer): overflow: clear data "
<<
delnum
<<
" records."
<<
endl
;
return
;
}
if
(
ibufSize
==
0
)
return
;
dbinfo
<<
myname
<<
"(flushInsertBuffer): write insert buffer to DB.."
<<
endl
;
dbinfo
<<
myname
<<
"(flushInsertBuffer): write insert buffer
["
<<
ibufSize
<<
"]
to DB.."
<<
endl
;
if
(
!
db
->
copy
(
"main_history"
,
tblcols
,
ibuf
)
)
{
...
...
@@ -254,18 +260,20 @@ void DBServer_PostgreSQL::sensorInfo( const UniSetTypes::SensorMessage* si )
#endif
// (date, time, time_usec, sensor_id, value, node)
PostgreSQLInterface
::
Record
rec
;
rec
.
push_back
(
dateToString
(
si
->
sm_tv_sec
,
"-"
));
// date
rec
.
push_back
(
timeToString
(
si
->
sm_tv_sec
,
":"
));
// time
rec
.
push_back
(
std
::
to_string
(
si
->
sm_tv_usec
));
rec
.
push_back
(
std
::
to_string
(
si
->
id
));
rec
.
push_back
(
std
::
to_string
(
si
->
value
));
rec
.
push_back
(
std
::
to_string
(
si
->
node
));
PostgreSQLInterface
::
Record
rec
=
{
dateToString
(
si
->
sm_tv_sec
,
"-"
),
// date
timeToString
(
si
->
sm_tv_sec
,
":"
),
// time
std
::
to_string
(
si
->
sm_tv_usec
),
std
::
to_string
(
si
->
id
),
std
::
to_string
(
si
->
value
),
std
::
to_string
(
si
->
node
),
};
ibuf
.
push_back
(
std
::
move
(
rec
));
ibufSize
++
;
if
(
ibufSize
>
ibufMaxSize
)
if
(
ibufSize
>
=
ibufMaxSize
)
flushInsertBuffer
();
}
catch
(
const
Exception
&
ex
)
...
...
@@ -316,9 +324,11 @@ void DBServer_PostgreSQL::initDBServer()
string
dbpass
(
conf
->
getArgParam
(
"--"
+
prefix
+
"-dbpass"
,
it
.
getProp
(
"dbpass"
)));
unsigned
int
dbport
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-dbport"
,
it
.
getProp
(
"dbport"
),
5432
);
ibufMaxSize
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-ibufMaxSize"
,
it
.
getProp
(
"ibufMaxSize"
),
5000
);
ibufSyncTimeout
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-ibufSyncTimeout"
,
it
.
getProp
(
"ibufSyncTimeout"
),
15000
);
std
::
string
sfactor
=
conf
->
getArg2Param
(
"--"
+
prefix
+
"-ibufOverflowCleanFactor"
,
it
.
getProp
(
"ibufOverflowCleanFactor"
),
"0.5"
);
ibufMaxSize
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-ibuf-maxsize"
,
it
.
getProp
(
"ibufMaxSize"
),
2000
);
ibuf
.
reserve
(
ibufMaxSize
);
ibufSyncTimeout
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-ibuf-sync-timeout"
,
it
.
getProp
(
"ibufSyncTimeout"
),
15000
);
std
::
string
sfactor
=
conf
->
getArg2Param
(
"--"
+
prefix
+
"-ibuf-overflow-cleanfactor"
,
it
.
getProp
(
"ibufOverflowCleanFactor"
),
"0.5"
);
ibufOverflowCleanFactor
=
atof
(
sfactor
.
c_str
());
tblMap
[
UniSetTypes
::
Message
::
SensorInfo
]
=
"main_history"
;
...
...
@@ -505,9 +515,9 @@ void DBServer_PostgreSQL::help_print( int argc, const char* const* argv )
cout
<<
"--prefix-reconnectTime msec - reconnect time. Default: 30000 msec "
<<
endl
;
cout
<<
"Insert buffer:"
<<
endl
;
cout
<<
"--prefix-ibuf
MaxSize sz - INSERT-buffer size. Default: 5
000"
<<
endl
;
cout
<<
"--prefix-ibuf
SyncTimeout msec
- INSERT-buffer sync timeout. Default: 15000 msec"
<<
endl
;
cout
<<
"--prefix-ibuf
OverflowCleanFactor [0...1]
- INSERT-buffer overflow clean factor. Default: 0.5"
<<
endl
;
cout
<<
"--prefix-ibuf
-maxsize sz - INSERT-buffer size. Default: 2
000"
<<
endl
;
cout
<<
"--prefix-ibuf
-sync-timeout msec
- INSERT-buffer sync timeout. Default: 15000 msec"
<<
endl
;
cout
<<
"--prefix-ibuf
-overflow-cleanfactor [0...1]
- INSERT-buffer overflow clean factor. Default: 0.5"
<<
endl
;
cout
<<
"Query buffer:"
<<
endl
;
cout
<<
"--prefix-buffer-size sz - The buffer in case the database is unavailable. Default: 200"
<<
endl
;
...
...
extensions/DBServer-PostgreSQL/DBServer_PostgreSQL.h
View file @
2f800c5f
...
...
@@ -27,15 +27,23 @@
* \brief The DBServer_PostgreSQL class
* Реализация работы с PostgreSQL.
*
* Т.к. основная работа
DBServer-а
это частая запись данных, то сделана следующая оптимизация:
* Т.к. основная работа
сервера -
это частая запись данных, то сделана следующая оптимизация:
* Создаётся insert-буфер настраиваемого размера (ibufMaxSize).
* Как только буфер заполняется, он пишется в БД одним "оптимизированным" запросом.
* Помимо этого буфер скидывается, если прошло ibufSyncTimeout мсек или если пришёл запрос
* на UPDATE данных.
*
* В случае если буфер переполняется (например нет связи с БД), то он чистится. При этом сколько
* записей удалять определяется коэффициентом
w
bufOverflowCleanFactor={0...1}.
* записей удалять определяется коэффициентом
i
bufOverflowCleanFactor={0...1}.
* А также флаг lastRemove определяет удалять с конца или начала очереди.
*
* \warning Следует иметь ввиду, что чтобы не было постоянных "перевыделений памяти" буфер сделан на основе
* vector и в начале работы в памяти сразу(!) резервируется место под буфер.
* Во первых надо иметь ввиду, что буфер - это то, что потеряется если вдруг произойдёт сбой
* по питанию или программа вылетит. Поэтому если он большой, то будет потеряно много данных.
* И второе, т.к. это vector - то идёт выделение "непрерывного куска памяти", поэтому у ОС могут
* быть проблеммы найти "большой непрерывный кусок".
* Тем не менее реализация сделана на vector-е чтобы избежать лишних "перевыделений" (и сегментации) памяти во время работы.
*/
class
DBServer_PostgreSQL
:
public
DBServer
...
...
@@ -108,10 +116,10 @@ class DBServer_PostgreSQL:
// writeBuffer
const
std
::
list
<
std
::
string
>
tblcols
=
{
"date"
,
"time"
,
"time_usec"
,
"sensor_id"
,
"value"
,
"node"
};
typedef
std
::
list
<
PostgreSQLInterface
::
Record
>
InsertBuffer
;
typedef
std
::
vector
<
PostgreSQLInterface
::
Record
>
InsertBuffer
;
InsertBuffer
ibuf
;
size_t
ibufSize
=
{
0
};
size_t
ibufMaxSize
=
{
5
000
};
size_t
ibufMaxSize
=
{
2
000
};
timeout_t
ibufSyncTimeout
=
{
15000
};
void
flushInsertBuffer
();
float
ibufOverflowCleanFactor
=
{
0
.
5
};
// коэфициент {0...1} чистки буфера при переполнении
...
...
extensions/DBServer-PostgreSQL/PostgreSQLInterface.cc
View file @
2f800c5f
...
...
@@ -86,10 +86,14 @@ bool PostgreSQLInterface::close()
return
true
;
}
// -----------------------------------------------------------------------------------------
bool
PostgreSQLInterface
::
copy
(
const
std
::
string
&
tblname
,
const
std
::
list
<
std
::
string
>&
cols
,
const
std
::
list
<
Record
>&
data
)
bool
PostgreSQLInterface
::
copy
(
const
std
::
string
&
tblname
,
const
std
::
list
<
std
::
string
>&
cols
,
const
PostgreSQLInterface
::
Data
&
data
)
{
if
(
!
db
)
{
lastE
=
"no connection"
;
return
false
;
}
try
{
...
...
@@ -116,7 +120,10 @@ bool PostgreSQLInterface::copy( const std::string& tblname, const std::list<std:
bool
PostgreSQLInterface
::
insert
(
const
string
&
q
)
{
if
(
!
db
)
{
lastE
=
"no connection"
;
return
false
;
}
try
{
...
...
@@ -137,7 +144,10 @@ bool PostgreSQLInterface::insert( const string& q )
bool
PostgreSQLInterface
::
insertAndSaveRowid
(
const
string
&
q
)
{
if
(
!
db
)
{
lastE
=
"no connection"
;
return
false
;
}
std
::
string
qplus
=
q
+
" RETURNING id"
;
...
...
extensions/DBServer-PostgreSQL/PostgreSQLInterface.h
View file @
2f800c5f
...
...
@@ -50,9 +50,10 @@ class PostgreSQLInterface:
void
save_inserted_id
(
const
pqxx
::
result
&
res
);
typedef
std
::
list
<
std
::
string
>
Record
;
typedef
std
::
vector
<
Record
>
Data
;
// fast insert: Use COPY..from SDTIN..
virtual
bool
copy
(
const
std
::
string
&
tblname
,
const
std
::
list
<
std
::
string
>&
cols
,
const
std
::
list
<
Record
>
&
data
);
bool
copy
(
const
std
::
string
&
tblname
,
const
std
::
list
<
std
::
string
>&
cols
,
const
Data
&
data
);
virtual
const
std
::
string
error
()
override
;
...
...
extensions/DBServer-PostgreSQL/test.cc
View file @
2f800c5f
...
...
@@ -61,7 +61,7 @@ int main(int argc, char** argv)
if
(
ver
==
3
)
{
std
::
list
<
std
::
string
>
cols
=
{
"date"
,
"time"
,
"time_usec"
,
"sensor_id"
,
"value"
,
"node"
};
std
::
list
<
PostgreSQLInterface
::
Record
>
data
;
PostgreSQLInterface
::
Data
data
;
for
(
size_t
i
=
0
;
i
<
num
;
i
++
)
{
PostgreSQLInterface
::
Record
d
=
{
"now()"
,
"now()"
,
"0"
,
"7"
,
"1"
,
"3000"
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment