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
...
@@ -69,6 +69,7 @@ Version 2.5
- совместимость между 64bit и 32bit - для этого нужно отказаться от использования сырого long и перейти либо на int32_t либо CORBA::Long.
- совместимость между 64bit и 32bit - для этого нужно отказаться от использования сырого long и перейти либо на int32_t либо CORBA::Long.
- timeout_t getSharedMemoryReadyTimeout()!
libev
libev
=======
=======
...
@@ -76,9 +77,12 @@ libev
...
@@ -76,9 +77,12 @@ libev
- UniSetActivator (обработка сигналов и возможно вынести сюда DefaultEventLoop) (на подумать)
- UniSetActivator (обработка сигналов и возможно вынести сюда DefaultEventLoop) (на подумать)
SM: подумать насчёт асинхронности публикации событий и посылки уведомления (setValue/push) через очередь..
SM: подумать насчёт асинхронности публикации событий и посылки уведомления (setValue/push) через очередь..
// worker-ы рассылающие сообщения, очередь заданий, конфигурирование количества worker-ов, основной поток ждёт если нет свободных.
SM: Подумать насчёт применения https://github.com/efficient/libcuckoo
SM: Подумать насчёт применения https://github.com/efficient/libcuckoo
DB: Сделать регулируемый буфер на INSERT-ы БД, чтобы поберечь винт (DBServer_PGSQL, DBServer_MySQL...) // по времени или по количеству
version 3
version 3
=========
=========
- подумать нужен ли нам где-то ZeroMQ (zerorpc) (вместо omniORB?)
- подумать нужен ли нам где-то ZeroMQ (zerorpc) (вместо omniORB?)
...
@@ -98,3 +102,5 @@ UResolver (или ObjectRepository) позволяющего манипулир
...
@@ -98,3 +102,5 @@ UResolver (или ObjectRepository) позволяющего манипулир
- вместо commoncpp,libxml2,DebugStream и т.п. перейти всё-таки на boost?
- вместо commoncpp,libxml2,DebugStream и т.п. перейти всё-таки на boost?
- подумать возможно стоит переходить на lockfree-библиотеку libcds..(актуально для многопроцессорных систем)
- подумать возможно стоит переходить на 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:
...
@@ -84,7 +84,7 @@ There are set of base components to construct this kind of systems:
* base interfaces for your implementation of control algorithms.
* base interfaces for your implementation of control algorithms.
* algorithms for the discrete and analog input/output based on COMEDI interface.
* algorithms for the discrete and analog input/output based on COMEDI interface.
* IPC mechanism based on CORBA (omniORB).
* 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.
* Web interface to display logging and statistic information.
* utilities for system's configuration based on XML.
* 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()
...
@@ -203,13 +203,13 @@ void DBServer_PostgreSQL::flushInsertBuffer()
// Чистим заданное число
// Чистим заданное число
size_t
delnum
=
lroundf
(
ibufSize
*
ibufOverflowCleanFactor
);
size_t
delnum
=
lroundf
(
ibufSize
*
ibufOverflowCleanFactor
);
InsertBuffer
::
iterator
end
=
ibuf
.
end
();
auto
end
=
ibuf
.
end
();
InsertBuffer
::
iterator
beg
=
ibuf
.
end
();
auto
beg
=
ibuf
.
end
();
// Удаляем последние (новые)
// Удаляем последние (новые)
if
(
lastRemove
)
if
(
lastRemove
)
{
{
std
::
advance
(
end
,
-
delnum
);
std
::
advance
(
beg
,
-
delnum
);
}
}
else
else
{
{
...
@@ -220,12 +220,18 @@ void DBServer_PostgreSQL::flushInsertBuffer()
...
@@ -220,12 +220,18 @@ void DBServer_PostgreSQL::flushInsertBuffer()
}
}
ibuf
.
erase
(
beg
,
end
);
ibuf
.
erase
(
beg
,
end
);
ibufSize
-=
delnum
;
if
(
ibufSize
<
0
)
ibufSize
=
0
;
dbwarn
<<
myname
<<
"(flushInsertBuffer): overflow: clear data "
<<
delnum
<<
" records."
<<
endl
;
return
;
}
}
if
(
ibufSize
==
0
)
if
(
ibufSize
==
0
)
return
;
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
)
)
if
(
!
db
->
copy
(
"main_history"
,
tblcols
,
ibuf
)
)
{
{
...
@@ -254,18 +260,20 @@ void DBServer_PostgreSQL::sensorInfo( const UniSetTypes::SensorMessage* si )
...
@@ -254,18 +260,20 @@ void DBServer_PostgreSQL::sensorInfo( const UniSetTypes::SensorMessage* si )
#endif
#endif
// (date, time, time_usec, sensor_id, value, node)
// (date, time, time_usec, sensor_id, value, node)
PostgreSQLInterface
::
Record
rec
;
PostgreSQLInterface
::
Record
rec
=
rec
.
push_back
(
dateToString
(
si
->
sm_tv_sec
,
"-"
));
// date
{
rec
.
push_back
(
timeToString
(
si
->
sm_tv_sec
,
":"
));
// time
dateToString
(
si
->
sm_tv_sec
,
"-"
),
// date
rec
.
push_back
(
std
::
to_string
(
si
->
sm_tv_usec
));
timeToString
(
si
->
sm_tv_sec
,
":"
),
// time
rec
.
push_back
(
std
::
to_string
(
si
->
id
));
std
::
to_string
(
si
->
sm_tv_usec
),
rec
.
push_back
(
std
::
to_string
(
si
->
value
));
std
::
to_string
(
si
->
id
),
rec
.
push_back
(
std
::
to_string
(
si
->
node
));
std
::
to_string
(
si
->
value
),
std
::
to_string
(
si
->
node
),
};
ibuf
.
push_back
(
std
::
move
(
rec
));
ibuf
.
push_back
(
std
::
move
(
rec
));
ibufSize
++
;
ibufSize
++
;
if
(
ibufSize
>
ibufMaxSize
)
if
(
ibufSize
>
=
ibufMaxSize
)
flushInsertBuffer
();
flushInsertBuffer
();
}
}
catch
(
const
Exception
&
ex
)
catch
(
const
Exception
&
ex
)
...
@@ -316,9 +324,11 @@ void DBServer_PostgreSQL::initDBServer()
...
@@ -316,9 +324,11 @@ void DBServer_PostgreSQL::initDBServer()
string
dbpass
(
conf
->
getArgParam
(
"--"
+
prefix
+
"-dbpass"
,
it
.
getProp
(
"dbpass"
)));
string
dbpass
(
conf
->
getArgParam
(
"--"
+
prefix
+
"-dbpass"
,
it
.
getProp
(
"dbpass"
)));
unsigned
int
dbport
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-dbport"
,
it
.
getProp
(
"dbport"
),
5432
);
unsigned
int
dbport
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-dbport"
,
it
.
getProp
(
"dbport"
),
5432
);
ibufMaxSize
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-ibufMaxSize"
,
it
.
getProp
(
"ibufMaxSize"
),
5000
);
ibufMaxSize
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-ibuf-maxsize"
,
it
.
getProp
(
"ibufMaxSize"
),
2000
);
ibufSyncTimeout
=
conf
->
getArgPInt
(
"--"
+
prefix
+
"-ibufSyncTimeout"
,
it
.
getProp
(
"ibufSyncTimeout"
),
15000
);
ibuf
.
reserve
(
ibufMaxSize
);
std
::
string
sfactor
=
conf
->
getArg2Param
(
"--"
+
prefix
+
"-ibufOverflowCleanFactor"
,
it
.
getProp
(
"ibufOverflowCleanFactor"
),
"0.5"
);
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
());
ibufOverflowCleanFactor
=
atof
(
sfactor
.
c_str
());
tblMap
[
UniSetTypes
::
Message
::
SensorInfo
]
=
"main_history"
;
tblMap
[
UniSetTypes
::
Message
::
SensorInfo
]
=
"main_history"
;
...
@@ -505,9 +515,9 @@ void DBServer_PostgreSQL::help_print( int argc, const char* const* argv )
...
@@ -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
<<
"--prefix-reconnectTime msec - reconnect time. Default: 30000 msec "
<<
endl
;
cout
<<
"Insert buffer:"
<<
endl
;
cout
<<
"Insert buffer:"
<<
endl
;
cout
<<
"--prefix-ibuf
MaxSize sz - INSERT-buffer size. Default: 5
000"
<<
endl
;
cout
<<
"--prefix-ibuf
-maxsize sz - INSERT-buffer size. Default: 2
000"
<<
endl
;
cout
<<
"--prefix-ibuf
SyncTimeout msec
- INSERT-buffer sync timeout. Default: 15000 msec"
<<
endl
;
cout
<<
"--prefix-ibuf
-sync-timeout 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
-overflow-cleanfactor [0...1]
- INSERT-buffer overflow clean factor. Default: 0.5"
<<
endl
;
cout
<<
"Query buffer:"
<<
endl
;
cout
<<
"Query buffer:"
<<
endl
;
cout
<<
"--prefix-buffer-size sz - The buffer in case the database is unavailable. Default: 200"
<<
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 @@
...
@@ -27,15 +27,23 @@
* \brief The DBServer_PostgreSQL class
* \brief The DBServer_PostgreSQL class
* Реализация работы с PostgreSQL.
* Реализация работы с PostgreSQL.
*
*
* Т.к. основная работа
DBServer-а
это частая запись данных, то сделана следующая оптимизация:
* Т.к. основная работа
сервера -
это частая запись данных, то сделана следующая оптимизация:
* Создаётся insert-буфер настраиваемого размера (ibufMaxSize).
* Создаётся insert-буфер настраиваемого размера (ibufMaxSize).
* Как только буфер заполняется, он пишется в БД одним "оптимизированным" запросом.
* Как только буфер заполняется, он пишется в БД одним "оптимизированным" запросом.
* Помимо этого буфер скидывается, если прошло ibufSyncTimeout мсек или если пришёл запрос
* Помимо этого буфер скидывается, если прошло ibufSyncTimeout мсек или если пришёл запрос
* на UPDATE данных.
* на UPDATE данных.
*
*
* В случае если буфер переполняется (например нет связи с БД), то он чистится. При этом сколько
* В случае если буфер переполняется (например нет связи с БД), то он чистится. При этом сколько
* записей удалять определяется коэффициентом
w
bufOverflowCleanFactor={0...1}.
* записей удалять определяется коэффициентом
i
bufOverflowCleanFactor={0...1}.
* А также флаг lastRemove определяет удалять с конца или начала очереди.
* А также флаг lastRemove определяет удалять с конца или начала очереди.
*
* \warning Следует иметь ввиду, что чтобы не было постоянных "перевыделений памяти" буфер сделан на основе
* vector и в начале работы в памяти сразу(!) резервируется место под буфер.
* Во первых надо иметь ввиду, что буфер - это то, что потеряется если вдруг произойдёт сбой
* по питанию или программа вылетит. Поэтому если он большой, то будет потеряно много данных.
* И второе, т.к. это vector - то идёт выделение "непрерывного куска памяти", поэтому у ОС могут
* быть проблеммы найти "большой непрерывный кусок".
* Тем не менее реализация сделана на vector-е чтобы избежать лишних "перевыделений" (и сегментации) памяти во время работы.
*/
*/
class
DBServer_PostgreSQL
:
class
DBServer_PostgreSQL
:
public
DBServer
public
DBServer
...
@@ -108,10 +116,10 @@ class DBServer_PostgreSQL:
...
@@ -108,10 +116,10 @@ class DBServer_PostgreSQL:
// writeBuffer
// writeBuffer
const
std
::
list
<
std
::
string
>
tblcols
=
{
"date"
,
"time"
,
"time_usec"
,
"sensor_id"
,
"value"
,
"node"
};
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
;
InsertBuffer
ibuf
;
size_t
ibufSize
=
{
0
};
size_t
ibufSize
=
{
0
};
size_t
ibufMaxSize
=
{
5
000
};
size_t
ibufMaxSize
=
{
2
000
};
timeout_t
ibufSyncTimeout
=
{
15000
};
timeout_t
ibufSyncTimeout
=
{
15000
};
void
flushInsertBuffer
();
void
flushInsertBuffer
();
float
ibufOverflowCleanFactor
=
{
0
.
5
};
// коэфициент {0...1} чистки буфера при переполнении
float
ibufOverflowCleanFactor
=
{
0
.
5
};
// коэфициент {0...1} чистки буфера при переполнении
...
...
extensions/DBServer-PostgreSQL/PostgreSQLInterface.cc
View file @
2f800c5f
...
@@ -86,10 +86,14 @@ bool PostgreSQLInterface::close()
...
@@ -86,10 +86,14 @@ bool PostgreSQLInterface::close()
return
true
;
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
)
if
(
!
db
)
{
lastE
=
"no connection"
;
return
false
;
return
false
;
}
try
try
{
{
...
@@ -116,7 +120,10 @@ bool PostgreSQLInterface::copy( const std::string& tblname, const std::list<std:
...
@@ -116,7 +120,10 @@ bool PostgreSQLInterface::copy( const std::string& tblname, const std::list<std:
bool
PostgreSQLInterface
::
insert
(
const
string
&
q
)
bool
PostgreSQLInterface
::
insert
(
const
string
&
q
)
{
{
if
(
!
db
)
if
(
!
db
)
{
lastE
=
"no connection"
;
return
false
;
return
false
;
}
try
try
{
{
...
@@ -137,7 +144,10 @@ bool PostgreSQLInterface::insert( const string& q )
...
@@ -137,7 +144,10 @@ bool PostgreSQLInterface::insert( const string& q )
bool
PostgreSQLInterface
::
insertAndSaveRowid
(
const
string
&
q
)
bool
PostgreSQLInterface
::
insertAndSaveRowid
(
const
string
&
q
)
{
{
if
(
!
db
)
if
(
!
db
)
{
lastE
=
"no connection"
;
return
false
;
return
false
;
}
std
::
string
qplus
=
q
+
" RETURNING id"
;
std
::
string
qplus
=
q
+
" RETURNING id"
;
...
...
extensions/DBServer-PostgreSQL/PostgreSQLInterface.h
View file @
2f800c5f
...
@@ -50,9 +50,10 @@ class PostgreSQLInterface:
...
@@ -50,9 +50,10 @@ class PostgreSQLInterface:
void
save_inserted_id
(
const
pqxx
::
result
&
res
);
void
save_inserted_id
(
const
pqxx
::
result
&
res
);
typedef
std
::
list
<
std
::
string
>
Record
;
typedef
std
::
list
<
std
::
string
>
Record
;
typedef
std
::
vector
<
Record
>
Data
;
// fast insert: Use COPY..from SDTIN..
// 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
;
virtual
const
std
::
string
error
()
override
;
...
...
extensions/DBServer-PostgreSQL/test.cc
View file @
2f800c5f
...
@@ -61,7 +61,7 @@ int main(int argc, char** argv)
...
@@ -61,7 +61,7 @@ int main(int argc, char** argv)
if
(
ver
==
3
)
if
(
ver
==
3
)
{
{
std
::
list
<
std
::
string
>
cols
=
{
"date"
,
"time"
,
"time_usec"
,
"sensor_id"
,
"value"
,
"node"
};
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
++
)
for
(
size_t
i
=
0
;
i
<
num
;
i
++
)
{
{
PostgreSQLInterface
::
Record
d
=
{
"now()"
,
"now()"
,
"0"
,
"7"
,
"1"
,
"3000"
};
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