-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathREADME_RUS
153 lines (123 loc) · 3.94 KB
/
README_RUS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
С помощью класса CLogParser можно настроить репликацию у любого демона, работающего с базой данных MYSQL (Версия не ниже 5.1 и должна быть настроена Row-Based репликация). Класс-потомок CLogParser должен определить три виртуальных функции:
int on_insert(const mysql::CTable& tbl, const mysql::CTable::TRows& rows);
int on_update(const mysql::CTable& tbl, const mysql::CTable::TRows& rows, const mysql::CTable::TRows& old_rows);
int on_delete(const mysql::CTable& tbl, const mysql::CTable::TRows& rows);
tbl -- изменяемая таблица
rows -- новые строки таблицы (в on_delete -- это удаленные строки)
old_rows -- старые строки, которые были изменены после UPDATE-запроса
Класс mysql::CTable::TRows представляет собой std::list<mysql::CRow>. Для класса CRow определены операторы:
const CValue& operator[](const std::string& name) const;
const CValue& operator[](size_t i) const;
Для извлечения значения в нужном формате из класса CValue предусмотрены функции:
typedef uint16_t TYear;
typedef struct
{
TYear y;
uint8_t m;
uint8_t d;
} TDate;
typedef struct
{
uint8_t h;
uint8_t m;
uint8_t s;
} TTime;
typedef struct
{
TDate date;
TTime time;
} TDateTime;
int8_t as_int8() const;
int16_t as_int16() const;
int32_t as_int32() const;
int64_t as_int64() const;
uint8_t as_uint8() const;
uint16_t as_uint16() const;
uint32_t as_uint32() const;
uint64_t as_uint64() const;
double as_double() const;
float as_float() const;
bool as_boolean() const;
time_t as_timestamp() const;
TDateTime as_datetime() const;
TDate as_date() const;
TTime as_time() const;
TYear as_year() const;
std::string as_string() const;
const char* as_string(size_t* length) const;
void as_string(std::string& dst) const;
uint64_t as_enum() const;
uint64_t as_set() const;
Чтобы указать, для каких таблиц следует отлавливать изменения, нужно использовать функцию:
void watch(const std::string& db_name, const std::string& table_name);
Репликация запускается отдельным потоком, в котором должен быть слeдующий цикл:
while (dispatch())
{
try
{
dispatch_events();
}
catch (const std::exception& e)
{
sleep(1);
}
}
Для завершения репликации нужно вызвать функцию stop_event_loop().
Пример кода:
class my_class : public mysql::CLogParser
{
...
pthread_t th_repl;
...
~my_class()
{
...
stop_event_loop();
::pthread_kill(th_repl, SIGTERM);
...
}
...
void replication_thread_proc()
{
while (dispatch())
{
try
{
dispatch_events();
}
catch (const std::exception& e)
{
fprintf(stderr, "catch exception: %s\n", e.what());
sleep(1);
}
}
}
void connect_mysql_repl(const char* host, const char* user, const char* passwd, int port, int slave_id)
{
set_connection_params(host, slave_id, user, passwd, port);
watch("db1", "db1_table1");
watch("db1", "db1_table2");
watch("db2", "db2_table1");
prepare();
}
int on_insert(const mysql::CTable& tbl, const mysql::CTable::TRows& rows)
{
if (strcasecmp(tbl.get_table_name(), "db1_table1") == 0)
{
for (mysql::CTable::TRows::const_iterator it = rows.begin(); it != rows.end(); ++it)
{
fprintf(stdout, "%u\n", *it["id"].as_uint32());
}
}
return 0;
}
int on_update(const mysql::CTable& tbl, const mysql::CTable::TRows& rows, const mysql::CTable::TRows& old_rows)
{
return 0;
}
int on_delete(const mysql::CTable& tbl, const mysql::CTable::TRows& rows)
{
return 0;
}
...
};