Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/cluster/classes/general/ |
Upload File : |
<?php IncludeModuleLangFile(__FILE__); abstract class CAllClusterDBNode { public function CheckFields(&$arFields, $ID) { global $APPLICATION; $aMsg = []; if (array_key_exists('NAME', $arFields)) { $arFields['NAME'] = trim($arFields['NAME']); } if (array_key_exists('ACTIVE', $arFields)) { $arFields['ACTIVE'] = $arFields['ACTIVE'] === 'Y' ? 'Y' : 'N'; } if (array_key_exists('SELECTABLE', $arFields)) { $arFields['SELECTABLE'] = $arFields['SELECTABLE'] === 'N' ? 'N' : 'Y'; } if (array_key_exists('WEIGHT', $arFields)) { $weight = intval($arFields['WEIGHT']); if ($weight < 0) { $weight = 0; } elseif ($weight > 100) { $weight = 100; } $arFields['WEIGHT'] = $weight; } if ( (isset($arFields['ACTIVE']) && $arFields['ACTIVE'] == 'Y') && $arFields['ROLE_ID'] != 'SLAVE' ) { $obCheck = new CClusterDBNodeCheck; $nodeDB = $obCheck->SlaveNodeConnection( $arFields['DB_HOST'], $arFields['DB_NAME'], $arFields['DB_LOGIN'], $arFields['DB_PASSWORD'], $arFields['ROLE_ID'] == 'MASTER' ? $arFields['MASTER_HOST'] : false, $arFields['ROLE_ID'] == 'MASTER' ? $arFields['MASTER_PORT'] : false ); if (is_object($nodeDB)) { $arFields['SERVER_ID'] = intval($obCheck->GetServerVariable($nodeDB, 'server_id')); } else { if (!array_key_exists('STATUS', $arFields)) { $arFields['STATUS'] = 'OFFLINE'; } $aMsg[] = ['id' => '', 'text' => $nodeDB]; } } if (!empty($aMsg)) { $e = new CAdminException($aMsg); $APPLICATION->ThrowException($e); return false; } return true; } abstract public static function GetUpTime($node_id); public static function GetByID($node_id, $arVirtNode=false) { global $DB, $CACHE_MANAGER; static $arNodes = false; static $arVirtNodes = []; //This code sets and gets virtual nodes //needed to test connection just before //save node credentials into db if (preg_match('/^v(\d+)$/', $node_id)) { if (is_array($arVirtNode)) { $arVirtNodes[$node_id] = $arVirtNode; return true; } else { return $arVirtNodes[$node_id]; } } //Normal method continues here $node_id = intval($node_id); if ($arNodes === false) { $cache_id = 'db_nodes'; if ( CACHED_b_cluster_dbnode !== false && $CACHE_MANAGER->Read(CACHED_b_cluster_dbnode, $cache_id, 'b_cluster_dbnode') ) { $arNodes = $CACHE_MANAGER->Get($cache_id); } else { $arNodes = []; $rs = $DB->Query('SELECT * FROM b_cluster_dbnode ORDER BY ID', false, '', ['fixed_connection' => true]); while ($ar = $rs->Fetch()) { $arNodes[intval($ar['ID'])] = $ar; } if (CACHED_b_cluster_dbnode !== false) { $CACHE_MANAGER->Set($cache_id, $arNodes); } } } return $arNodes[$node_id]; } public function Add($arFields) { global $DB, $CACHE_MANAGER; if (!$this->CheckFields($arFields, 0)) { return false; } if (!array_key_exists('ACTIVE', $arFields)) { $arFields['ACTIVE'] = 'Y'; } $ID = $DB->Add('b_cluster_dbnode', $arFields); if (CACHED_b_cluster_dbnode !== false) { $CACHE_MANAGER->CleanDir('b_cluster_dbnode'); } return $ID; } public static function Delete($ID, $bStopSlave = true) { global $DB, $CACHE_MANAGER; $ID = intval($ID); $res = $DB->Query('select ID from b_cluster_dbnode WHERE ID=1 OR MASTER_ID = ' . $ID, false, '', ['fixed_connection' => true]); if ($bStopSlave) { while ($ar = $res->Fetch()) { if (!CClusterSlave::Stop($ar['ID'])) { return false; } } } if ($res) { $res = $DB->Query('DELETE FROM b_cluster_dbnode WHERE ID = ' . $ID, false, '', ['fixed_connection' => true]); } if (CACHED_b_cluster_dbnode !== false) { $CACHE_MANAGER->CleanDir('b_cluster_dbnode'); } return $res; } public function Update($ID, $arFields) { global $DB, $CACHE_MANAGER; $ID = intval($ID); if ($ID <= 0) { return false; } if (!$this->CheckFields($arFields, $ID)) { return false; } unset($arFields['GROUP_ID']); $strUpdate = $DB->PrepareUpdate('b_cluster_dbnode', $arFields); if ($strUpdate <> '') { $strSql = ' UPDATE b_cluster_dbnode SET ' . $strUpdate . ' WHERE ID = ' . $ID . ' '; if (!$DB->Query($strSql, false, '', ['fixed_connection' => true])) { return false; } } if (CACHED_b_cluster_dbnode !== false) { $CACHE_MANAGER->CleanDir('b_cluster_dbnode'); } return true; } public static function SetOffline($node_id) { global $DB, $CACHE_MANAGER, $APPLICATION; $rs = $DB->Query(" UPDATE b_cluster_dbnode SET STATUS = 'OFFLINE' WHERE ID = " . intval($node_id) . " AND STATUS <> 'OFFLINE' ", false, '', ['fixed_connection' => true]); if ($rs->AffectedRowsCount() > 0) { if (CACHED_b_cluster_dbnode !== false) { $CACHE_MANAGER->CleanDir('b_cluster_dbnode'); } if (!CAgent::AddAgent('CClusterDBNode::BringOnline();', 'cluster', 'N', 10)) { $APPLICATION->ResetException(); } } } public static function SetOnline($node_id) { global $DB, $CACHE_MANAGER; $DB->Query(" UPDATE b_cluster_dbnode SET STATUS = 'ONLINE' WHERE ID = " . intval($node_id) . ' ', false, '', ['fixed_connection' => true]); if (CACHED_b_cluster_dbnode !== false) { $CACHE_MANAGER->CleanDir('b_cluster_dbnode'); } } public static function BringOnline() { $rsOfflineNodes = CClusterDBNode::GetList([], ['=STATUS' => 'OFFLINE'], ['ID']); if ($arNode = $rsOfflineNodes->Fetch()) { ob_start(); $nodeDB = CDatabase::GetDBNodeConnection($arNode['ID'], true, false); ob_end_clean(); if (is_object($nodeDB)) { CClusterDBNode::SetOnline($arNode['ID']); } return 'CClusterDBNode::BringOnline();'; } return ''; } public static function GetList($arOrder=false, $arFilter=false, $arSelect=false) { global $DB; if (!is_array($arSelect)) { $arSelect = []; } if (count($arSelect) < 1) { $arSelect = [ 'ID', 'ACTIVE', 'ROLE_ID', 'NAME', 'DESCRIPTION', 'DB_HOST', 'DB_NAME', 'DB_LOGIN', 'DB_PASSWORD', 'MASTER_ID', 'SERVER_ID', 'STATUS', 'WEIGHT', 'SELECTABLE', 'GROUP_ID' ]; } if (!is_array($arOrder)) { $arOrder = []; } $arQueryOrder = []; foreach ($arOrder as $strColumn => $strDirection) { $strColumn = mb_strtoupper($strColumn); $strDirection = mb_strtoupper($strDirection) === 'ASC' ? 'ASC' : 'DESC'; switch ($strColumn) { case 'ID': case 'NAME': $arSelect[] = $strColumn; $arQueryOrder[$strColumn] = $strColumn . ' ' . $strDirection; break; } } $arQuerySelect = []; foreach ($arSelect as $strColumn) { $strColumn = mb_strtoupper($strColumn); switch ($strColumn) { case 'ID': case 'ACTIVE': case 'ROLE_ID': case 'NAME': case 'DESCRIPTION': case 'DB_HOST': case 'DB_NAME': case 'DB_LOGIN': case 'DB_PASSWORD': case 'MASTER_ID': case 'SERVER_ID': case 'STATUS': case 'WEIGHT': case 'SELECTABLE': case 'GROUP_ID': $arQuerySelect[$strColumn] = 'n.' . $strColumn; break; } } if (count($arQuerySelect) < 1) { $arQuerySelect = ['ID' => 'n.ID']; } $obQueryWhere = new CSQLWhere; $arFields = [ 'ID' => [ 'TABLE_ALIAS' => 'n', 'FIELD_NAME' => 'n.ID', 'FIELD_TYPE' => 'int', 'JOIN' => false, ], 'GROUP_ID' => [ 'TABLE_ALIAS' => 'n', 'FIELD_NAME' => 'n.GROUP_ID', 'FIELD_TYPE' => 'string', 'JOIN' => false, ], 'ROLE_ID' => [ 'TABLE_ALIAS' => 'n', 'FIELD_NAME' => 'n.ROLE_ID', 'FIELD_TYPE' => 'string', 'JOIN' => false, ], 'ACTIVE' => [ 'TABLE_ALIAS' => 'n', 'FIELD_NAME' => 'n.ACTIVE', 'FIELD_TYPE' => 'string', 'JOIN' => false, ], 'SERVER_ID' => [ 'TABLE_ALIAS' => 'n', 'FIELD_NAME' => 'n.SERVER_ID', 'FIELD_TYPE' => 'int', 'JOIN' => false, ], 'MASTER_ID' => [ 'TABLE_ALIAS' => 'n', 'FIELD_NAME' => 'n.MASTER_ID', 'FIELD_TYPE' => 'int', 'JOIN' => false, ], 'STATUS' => [ 'TABLE_ALIAS' => 'n', 'FIELD_NAME' => 'n.STATUS', 'FIELD_TYPE' => 'string', 'JOIN' => false, ], 'NAME' => [ 'TABLE_ALIAS' => 'n', 'FIELD_NAME' => 'n.NAME', 'FIELD_TYPE' => 'string', 'JOIN' => false, ], ]; $obQueryWhere->SetFields($arFields); if (!is_array($arFilter)) { $arFilter = []; } $strQueryWhere = $obQueryWhere->GetQuery($arFilter); $bDistinct = $obQueryWhere->bDistinctReqired; $strSql = ' SELECT ' . ($bDistinct ? 'DISTINCT' : '') . ' ' . implode(', ', $arQuerySelect) . ' FROM b_cluster_dbnode n ' . $obQueryWhere->GetJoins() . ' '; if ($strQueryWhere) { $strSql .= ' WHERE ' . $strQueryWhere . ' '; } if (count($arQueryOrder) > 0) { $strSql .= ' ORDER BY ' . implode(', ', $arQueryOrder) . ' '; } return $DB->Query($strSql, false, '', ['fixed_connection' => true]); } public static function getServerList() { global $DB; $result = []; $rsData = $DB->Query(' SELECT ID, GROUP_ID, ROLE_ID, DB_HOST FROM b_cluster_dbnode ORDER BY GROUP_ID IS NULL, GROUP_ID, ID '); while ($arData = $rsData->Fetch()) { if ($arData['ROLE_ID'] == 'SLAVE' || $arData['ROLE_ID'] == 'MASTER') { $edit_url = '/bitrix/admin/cluster_slave_edit.php?lang=' . LANGUAGE_ID . '&group_id=' . $arData['GROUP_ID'] . '&ID=' . $arData['ID']; } elseif ($arData['ROLE_ID'] == 'MODULE') { $edit_url = '/bitrix/admin/cluster_dbnode_edit.php?lang=' . LANGUAGE_ID . '&ID=' . $arData['ID']; } else { $edit_url = ''; } $host = ''; $match = []; if ( preg_match('/\\(\\s*HOST\\s*=\\s*([^)]+)\\)/i', $arData['DB_HOST'], $match) || preg_match('/^([^:]+)(:|)/', $arData['DB_HOST'], $match) ) { if ($match[1] !== 'localhost' && $match[1] !== '127.0.0.1') { $host = $arData['DB_HOST']; } } $result[] = [ 'ID' => $arData['ID'], 'GROUP_ID' => $arData['GROUP_ID'], 'SERVER_TYPE' => 'database', 'ROLE_ID' => $arData['ROLE_ID'], 'HOST' => $arData['DB_HOST'], 'DEDICATED' => $host === '' ? 'N' : 'Y', 'EDIT_URL' => $edit_url, ]; } return $result; } public static function GetModules($node_id) { global $DB; static $arCache = false; if ($arCache === false) { $arCache = []; $rs = $DB->Query("SELECT * from b_option WHERE NAME='dbnode_id'", false, '', ['fixed_connection' => true]); while ($ar = $rs->Fetch()) { if (is_numeric($ar['VALUE'])) { $arCache[intval($ar['VALUE'])][$ar['MODULE_ID']] = $ar['MODULE_ID']; } } } if (isset($arCache[$node_id])) { return $arCache[$node_id]; } else { return []; } } public static function GetModulesForSharding() { $connection = \Bitrix\Main\Application::getConnection(); $arModules = []; if ($connection->getType() === 'mysql') { foreach (GetModuleEvents('cluster', 'OnGetTableList', true) as $arEvent) { $ar = ExecuteModuleEventEx($arEvent); if (is_array($ar)) { $cur_node_id = intval(COption::GetOptionString($ar['MODULE']->MODULE_ID, 'dbnode_id')); if ($cur_node_id < 1) { $cur_node_id = 1; } $cur_node_id = CClusterDBNode::GetByID($cur_node_id); $ar['TITLE'] = $ar['MODULE']->MODULE_NAME . ' (' . $cur_node_id['NAME'] . ')'; $arModules[$ar['MODULE']->MODULE_ID] = $ar; } } } return $arModules; } public static function GetListForModuleInstall() { return CClusterDBNode::GetList( ['NAME' => 'ASC','ID' => 'ASC'] ,['=ACTIVE' => 'Y', '=ROLE_ID' => 'MODULE', '=STATUS' => 'READY'] ,['ID', 'NAME'] ); } }