1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
slave.php
См. документацию.
1<?php
2
5
7
9{
10 public static function Pause($node_id)
11 {
12 global $DB;
13
14 $arNode = CClusterDBNode::GetByID($node_id);
15 if (!is_array($arNode))
16 {
17 return;
18 }
19
20 if ($node_id == 1)
21 {
22 $nodeDB = $DB;
23 }
24 else
25 {
26 ob_start();
27 $nodeDB = CDatabase::GetDBNodeConnection($arNode['ID'], true);
28 ob_end_clean();
29 }
30
31 if (!is_object($nodeDB))
32 {
33 return;
34 }
35
36 $rs = $nodeDB->Query('select pg_wal_replay_pause()', false, '', ['fixed_connection' => true]);
37 if ($rs)
38 {
39 $ob = new CClusterDBNode;
40 $ob->Update($arNode['ID'], ['STATUS' => 'PAUSED']);
41 }
42 }
43
44 public static function Resume($node_id)
45 {
46 global $DB;
47
48 $arNode = CClusterDBNode::GetByID($node_id);
49 if (!is_array($arNode))
50 {
51 return;
52 }
53
54 if ($node_id == 1)
55 {
56 $nodeDB = $DB;
57 }
58 else
59 {
60 ob_start();
61 $nodeDB = CDatabase::GetDBNodeConnection($arNode['ID'], true, false);
62 ob_end_clean();
63 }
64
65 if (!is_object($nodeDB))
66 {
67 return;
68 }
69
70 $rs = $nodeDB->Query('select pg_wal_replay_resume()', false, '', ['fixed_connection' => true]);
71 if ($rs)
72 {
73 $ob = new CClusterDBNode;
74 $ob->Update($arNode['ID'], ['STATUS' => 'ONLINE']);
75 }
76 }
77
78 public static function GetStatus($node_id, $bSlaveStatus = true, $bGlobalStatus = true, $bVariables = true)
79 {
80 global $DB;
81
82 $arNode = CClusterDBNode::GetByID($node_id);
83 if (!is_array($arNode))
84 {
85 return false;
86 }
87
88 if ($node_id == 1 || $arNode['MASTER_ID'] == 1)
89 {
90 $masterDB = $DB;
91 }
92 else
93 {
94 ob_start();
95 try
96 {
97 $masterDB = CDatabase::GetDBNodeConnection($arNode['MASTER_ID'], true, false);
98 }
99 catch (\Bitrix\Main\DB\ConnectionException $_)
100 {
101 $masterDB = false;
102 }
103 ob_end_clean();
104 }
105
106 if (!is_object($masterDB))
107 {
108 return false;
109 }
110
111 $arStatus = ['Rows_returned' => null];
112
113 if ($arNode['MASTER_ID'] <> '')
114 {
115 $arStatus = array_merge($arStatus, [
116 'state' => null,
117 'sync_state' => null,
118 'sent_lsn' => null,
119 'replay_lsn' => null,
120 'Seconds_Behind_Master' => null,
121 ]);
122
123 if ($bSlaveStatus)
124 {
125 $rs = $masterDB->Query('select STATE,SYNC_STATE,SENT_LSN,REPLAY_LSN,REPLAY_LAG from bx_cluster_stat_replication() WHERE CLIENT_ADDR = \'' . $masterDB->ForSql($arNode['DB_HOST']) . '\'', true, '', ['fixed_connection' => true]);
126 if (!$rs)
127 {
128 return false;
129 }
130
131 $ar = $rs->Fetch();
132 if (is_array($ar))
133 {
134 $arStatus['state'] = $ar['STATE'];
135 $arStatus['sync_state'] = $ar['SYNC_STATE'];
136 $arStatus['sent_lsn'] = $ar['SENT_LSN'];
137 $arStatus['replay_lsn'] = $ar['REPLAY_LSN'];
138 $hours = 0;
139 $minutes = 0;
140 $seconds = 0;
141 sscanf($ar['REPLAY_LAG'] ?: '00:00:00', '%d:%d:%d', $hours, $minutes, $seconds);
142 $arStatus['Seconds_Behind_Master'] = $hours * 3600 + $minutes * 60 + $seconds;
143 }
144 }
145 }
146
147 if ($bGlobalStatus)
148 {
149 if ($node_id == 1)
150 {
151 $nodeDB = $DB;
152 }
153 else
154 {
155 ob_start();
156 try
157 {
158 $nodeDB = CDatabase::GetDBNodeConnection($arNode['ID'], true, false);
159 }
160 catch (\Bitrix\Main\DB\ConnectionException $_)
161 {
162 $nodeDB = false;
163 }
164 ob_end_clean();
165 }
166
167 if (is_object($nodeDB))
168 {
169 $rs = $nodeDB->Query("select TUP_RETURNED from pg_stat_database where DATNAME = '" . $nodeDB->ForSql($nodeDB->DBName) . "'", true, '', ['fixed_connection' => true]);
170 if (is_object($rs))
171 {
172 while ($ar = $rs->Fetch())
173 {
174 if (!isset($arStatus['Rows_returned']))
175 {
176 $arStatus['Rows_returned'] = 0;
177 }
178
179 $arStatus['Rows_returned'] += $ar['TUP_RETURNED'];
180 }
181 }
182 }
183 }
184
185 return $arStatus;
186 }
187
188 public static function GetList(): array
189 {
190 global $DB;
191 static $slaves = false;
192 if ($slaves === false)
193 {
194 $cacheID = 'db_slaves_v2';
195
197 $cache = Application::getInstance()->getManagedCache();
198 if (
199 CACHED_b_cluster_dbnode !== false
200 && $cache->read(CACHED_b_cluster_dbnode, $cacheID, 'b_cluster_dbnode')
201 )
202 {
203 $slaves = $cache->get($cacheID);
204 }
205 else
206 {
207 $slaves = [];
208
209 $rs = $DB->Query("
210 SELECT ID, WEIGHT, ROLE_ID, GROUP_ID
211 FROM b_cluster_dbnode
212 WHERE STATUS = 'ONLINE' AND (SELECTABLE is null or SELECTABLE = 'Y')
213 ORDER BY ID
214 ", false, '', ['fixed_connection' => true]);
215 while ($ar = $rs->Fetch())
216 {
217 $slaves[intval($ar['ID'])] = $ar;
218 }
219
220 if (CACHED_b_cluster_dbnode !== false)
221 {
222 $cache->set($cacheID, $slaves);
223 }
224 }
225 }
226 return $slaves;
227 }
228
229 protected static function GetMaxSlaveDelay(): int
230 {
231 static $max_slave_delay = null;
232 if (!isset($max_slave_delay))
233 {
234 $max_slave_delay = (int) Option::get('cluster', 'max_slave_delay');
235 if (
236 Application::getInstance()->isInitialized()
237 && isset(Application::getInstance()->getKernelSession()['BX_REDIRECT_TIME'])
238 )
239 {
240 $redirect_delay = time() - Application::getInstance()->getKernelSession()['BX_REDIRECT_TIME'] + 1;
241 if (
242 $redirect_delay > 0
243 && $redirect_delay < $max_slave_delay
244 )
245 {
246 $max_slave_delay = $redirect_delay;
247 }
248 }
249 }
250 return $max_slave_delay;
251 }
252
253 protected static function IsSlaveOk($slave_id): bool
254 {
255 $cache = \Bitrix\Main\Data\Cache::createInstance();
256 if ($cache->initCache(
257 (int) Option::get('cluster', 'slave_status_cache_time'),
258 'cluster_slave_status_' . (int) $slave_id,
259 'cluster'
260 ))
261 {
262 $slaveStatus = $cache->getVars();
263 }
264 else
265 {
266 $slaveStatus = static::GetStatus($slave_id, true, false, false);
267 }
268
269 if (
270 !$slaveStatus
271 || $slaveStatus['Seconds_Behind_Master'] > static::GetMaxSlaveDelay()
272 || $slaveStatus['state'] != 'streaming'
273 )
274 {
275 if ($cache->startDataCache())
276 {
277 $cache->endDataCache($slaveStatus);
278 }
279 return false;
280 }
281 return true;
282 }
283
284 public static function GetRandomNode()
285 {
286 $slaves = static::GetList();
287 if (empty($slaves))
288 {
289 return false;
290 }
291
292 //Exclude slaves from other cluster groups
293 foreach ($slaves as $i => $slave)
294 {
295 $isOtherGroup = defined('BX_CLUSTER_GROUP') && ($slave['GROUP_ID'] != constant('BX_CLUSTER_GROUP'));
296 if (
297 defined('BX_CLUSTER_SLAVE_USE_ANY_GROUP')
298 && constant('BX_CLUSTER_SLAVE_USE_ANY_GROUP') === true
299 && $slave['ROLE_ID'] == 'SLAVE'
300 )
301 {
302 $isOtherGroup = false;
303 }
304
305 if ($isOtherGroup)
306 {
307 unset($slaves[$i]);
308 }
309 }
310
311 $found = false;
312 while (true)
313 {
314 if (empty($slaves))
315 {
316 return false;
317 }
318
319 $total_weight = 0;
320 foreach ($slaves as $i => $slave)
321 {
322 $total_weight += $slave['WEIGHT'];
323 $slaves[$i]['PIE_WEIGHT'] = $total_weight;
324 }
325
326 $rand = ($total_weight > 0 ? mt_rand(1, $total_weight) : 0);
327 foreach ($slaves as $i => $slave)
328 {
329 if ($rand <= $slave['PIE_WEIGHT'])
330 {
331 if ($slave['ROLE_ID'] == 'SLAVE')
332 {
333 if (!static::IsSlaveOk($slave['ID']))
334 {
335 unset($slaves[$i]);
336 continue 2;
337 }
338 }
339
340 $found = $slave;
341 break 2;
342 }
343 }
344 }
345
346 if (!$found || $found['ROLE_ID'] != 'SLAVE')
347 {
348 return false; //use main connection
349 }
350
351 return $found;
352 }
353}
Update($ID, $arFields)
Определения dbnode.php:187
static GetByID($node_id, $arVirtNode=false)
Определения dbnode.php:79
Определения dbnode.php:5
Определения slave.php:9
static GetRandomNode()
Определения slave.php:284
static GetStatus($node_id, $bSlaveStatus=true, $bGlobalStatus=true, $bVariables=true)
Определения slave.php:78
static Pause($node_id)
Определения slave.php:10
static GetMaxSlaveDelay()
Определения slave.php:229
static Resume($node_id)
Определения slave.php:44
static IsSlaveOk($slave_id)
Определения slave.php:253
$hours
Определения cron_html_pages.php:15
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
global $DB
Определения cron_frame.php:29
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
$ar
Определения options.php:199
$i
Определения factura.php:643
$rs
Определения action.php:82