function InitStep() { global $DB; $wizard =& $this->GetWizard(); $node_id = intval($wizard->GetVar('node_id')); if (!CModule::IncludeModule('cluster')) { $this->SetError(GetMessage('CLUWIZ_NO_MODULE_ERROR')); } elseif ($DB->type != "MYSQL") { $this->SetError(GetMessage('CLUWIZ_DATABASE_NOT_SUPPORTED')); } elseif ($node_id <= 1) { $this->SetError(GetMessage('CLUWIZ_NO_NODE_ERROR')); } else { $this->arNode = CClusterDBNode::GetByID($node_id); if (!is_array($this->arNode)) { $this->SetError(GetMessage('CLUWIZ_NO_NODE_ERROR')); } else { // $arNode["ROLE_ID"] == "SLAVE" // $arNode["STATUS"] == "READY" $this->nodeDB = CDatabase::GetDBNodeConnection($this->arNode["ID"], true, false); if (!is_object($this->nodeDB)) { $this->SetError(GetMessage('CLUWIZ_NO_CONN_ERROR')); } } } }
function ShowStepNoError() { $this->content = GetMessage('CLUWIZ_STEP1_CONTENT'); $this->content .= "<br />"; $obCheck = new CClusterDBNodeCheck(); $arCheckList = array_merge($obCheck->MainNodeCommon(CClusterDBNode::GetByID(1)), $obCheck->MainNodeForReplication(CClusterDBNode::GetByID(1)), $obCheck->MainNodeForSlave()); $this->ShowCheckList($arCheckList); if ($this->CheckListHasNoError($arCheckList)) { $this->SetNextStep("step2"); } else { $this->SetNextStep("step1"); } }
/** * @param string $node_id * @param boolean $bIgnoreErrors * @param boolean $bCheckStatus * * @return boolean|CDatabase */ public static function GetDBNodeConnection($node_id, $bIgnoreErrors = false, $bCheckStatus = true) { global $DB; if (!array_key_exists($node_id, self::$arNodes)) { if (CModule::IncludeModule('cluster')) { self::$arNodes[$node_id] = CClusterDBNode::GetByID($node_id); } else { self::$arNodes[$node_id] = false; } } $node =& self::$arNodes[$node_id]; if (is_array($node) && (!$bCheckStatus || $node["ACTIVE"] == "Y" && ($node["STATUS"] == "ONLINE" || $node["STATUS"] == "READY")) && !isset($node["ONHIT_ERROR"])) { if (!array_key_exists("DB", $node)) { $node_DB = new CDatabase(); $node_DB->type = $DB->type; $node_DB->debug = $DB->debug; $node_DB->DebugToFile = $DB->DebugToFile; $node_DB->bNodeConnection = true; $node_DB->node_id = $node_id; if ($node_DB->Connect($node["DB_HOST"], $node["DB_NAME"], $node["DB_LOGIN"], $node["DB_PASSWORD"], "node" . $node_id)) { if (defined("DELAY_DB_CONNECT") && DELAY_DB_CONNECT === true) { if ($node_DB->DoConnect("node" . $node_id)) { $node["DB"] = $node_DB; } } else { $node["DB"] = $node_DB; } } } if (array_key_exists("DB", $node)) { return $node["DB"]; } } if ($bIgnoreErrors) { return false; } else { if (file_exists($_SERVER["DOCUMENT_ROOT"] . BX_PERSONAL_ROOT . "/php_interface/dbconn_error.php")) { include $_SERVER["DOCUMENT_ROOT"] . BX_PERSONAL_ROOT . "/php_interface/dbconn_error.php"; } else { include $_SERVER["DOCUMENT_ROOT"] . BX_ROOT . "/modules/main/include/dbconn_error.php"; } die; } }
function InitStep() { global $DB; $wizard =& $this->GetWizard(); $node_id = intval($wizard->GetVar('node_id')); if (!CModule::IncludeModule('cluster')) { $this->SetError(GetMessage('CLUWIZ_NO_MODULE_ERROR')); } elseif ($DB->type != "MYSQL") { $this->SetError(GetMessage('CLUWIZ_DATABASE_NOT_SUPPORTED')); } elseif ($node_id <= 1) { $this->SetError(GetMessage('CLUWIZ_NO_NODE_ERROR')); } else { $this->arNode = CClusterDBNode::GetByID($node_id); if (!is_array($this->arNode)) { $this->SetError(GetMessage('CLUWIZ_NO_NODE_ERROR')); } else { // $arNode["ROLE_ID"] == "SLAVE" // $arNode["STATUS"] == "READY" $this->nodeDB = CDatabase::GetDBNodeConnection($this->arNode["ID"], true, false); if (!is_object($this->nodeDB)) { $this->SetError(GetMessage('CLUWIZ_NO_CONN_ERROR')); } else { $arGroup = CClusterGroup::GetArrayByID(intval($wizard->GetVar("group_id"))); if (!$arGroup) { $this->SetError(GetMessage('CLUWIZ_NO_GROUP_ERROR')); } else { $cData = new CClusterDBNode(); $rsData = $cData->GetList(array(), array("=ROLE_ID" => array("MAIN", "MASTER"), "=GROUP_ID" => $arGroup["ID"], "=STATUS" => "ONLINE")); $this->arMaster = $rsData->Fetch(); if (!$this->arMaster) { $this->SetError(GetMessage('CLUWIZ_NO_MASTER_ERROR')); } } } } } }
function ShowStepNoError() { global $APPLICATION; $wizard =& $this->GetWizard(); $path = $wizard->package->path; if (count($this->GetErrors()) == 0) { if ($wizard->GetVar('module')) { $module = $wizard->GetVar('module'); } else { $arNodeModules = CClusterDBNode::GetModules($wizard->GetVar('from_node_id')); $module = key($arNodeModules); } $arTables = false; foreach (GetModuleEvents("cluster", "OnGetTableList", true) as $arEvent) { if ($module === $arEvent["TO_MODULE_ID"]) { $arTables = ExecuteModuleEventEx($arEvent); break; } } if (is_array($arTables)) { $arTablesToDelete = array(); foreach ($arTables["TABLES"] as $table_name => $key_column) { if ($this->nodeDB->TableExists($table_name)) { $arTablesToDelete[] = $table_name; } } if (empty($arTablesToDelete)) { $this->content .= GetMessage("CLUWIZ_STEP2_NO_TABLES"); $this->SetNextStep("step4"); } else { if ($wizard->GetVar('to_node_id')) { $arNode = CClusterDBNode::GetByID($wizard->GetVar('to_node_id')); } else { $arNode = CClusterDBNode::GetByID($wizard->GetVar('node_id')); } $wizard->SetVar('action', ''); CJSCore::Init(array("ajax")); $APPLICATION->AddHeadScript($path . '/js/import.js'); $this->content .= GetMessage("CLUWIZ_STEP2_TABLES_EXIST"); $this->content .= '<br /><a style="text-decoration:none;border-bottom:1px dashed #2775C7;" onclick="if(document.getElementById(\'tables\').style.display==\'block\'){document.getElementById(\'tables\').style.display=\'none\';}else{document.getElementById(\'tables\').style.display=\'block\';}">' . GetMessage("CLUWIZ_STEP2_TABLES_LIST") . '</a>'; $this->content .= '<div id="tables" style="display:none">' . implode('<br />', $arTablesToDelete) . '</div>'; $this->content .= '<br /><br />' . $this->ShowCheckboxField('action', 'delete', array('id' => 'action', 'onclick' => 'if(this.checked){EnableButton();}else{DisableButton();}')) . '<label for="action">' . GetMessage("CLUWIZ_STEP2_DELETE_TABLES", array("#database#" => $arNode["NAME"])) . '</label>'; $this->content .= ' <script type="text/javascript"> var nextButtonID = "' . $wizard->GetNextButtonID() . '"; var formID = "' . $wizard->GetFormName() . '"; BX.ready(DisableButton); </script> '; $this->SetNextStep("step3"); } } } }
function GetStatus($node_id, $bSlaveStatus = true, $bGlobalStatus = true, $bVariables = true) { global $DB; $arNode = CClusterDBNode::GetByID($node_id); if (!is_array($arNode)) { return false; } if ($node_id == 1) { $nodeDB = $DB; } else { ob_start(); $nodeDB = CDatabase::GetDBNodeConnection($node_id, true, false); $error = ob_get_contents(); ob_end_clean(); } if (!is_object($nodeDB)) { return false; } $arStatus = array('server_id' => null); if ($bVariables) { $rs = $nodeDB->Query("show variables like 'server_id'", false, "", array("fixed_connection" => true)); if ($ar = $rs->Fetch()) { $arStatus['server_id'] = $ar["Value"]; } } $rsSlaves = CClusterDBNode::GetList(array(), array("=MASTER_ID" => $node_id)); if ($rsSlaves->Fetch()) { $arStatus = array_merge($arStatus, array('File' => null, 'Position' => null)); if ($bSlaveStatus) { $rs = $nodeDB->Query("SHOW MASTER STATUS", true, "", array("fixed_connection" => true)); if (!$rs) { return GetMessage("CLU_NO_PRIVILEGES", array("#sql#" => "GRANT REPLICATION CLIENT on *.* to '" . $nodeDB->DBLogin . "'@'%';")); } $ar = $rs->Fetch(); if (is_array($ar)) { foreach ($ar as $key => $value) { if ($key == 'Last_Error') { $key = 'Last_SQL_Error'; } if (array_key_exists($key, $arStatus)) { $arStatus[$key] = $value; } } } } } if (strlen($arNode["MASTER_ID"])) { $arStatus = array_merge($arStatus, array('Slave_IO_State' => null, 'Slave_IO_Running' => null, 'Read_Master_Log_Pos' => null, 'Slave_SQL_Running' => null, 'Exec_Master_Log_Pos' => null, 'Seconds_Behind_Master' => null, 'Last_IO_Error' => null, 'Last_SQL_Error' => null, 'Com_select' => null)); if ($bSlaveStatus) { $rs = $nodeDB->Query("SHOW SLAVE STATUS", true, "", array("fixed_connection" => true)); if (!$rs) { return GetMessage("CLU_NO_PRIVILEGES", array("#sql#" => "GRANT REPLICATION CLIENT on *.* to '" . $nodeDB->DBLogin . "'@'%';")); } $ar = $rs->Fetch(); if (is_array($ar)) { foreach ($ar as $key => $value) { if ($key == 'Last_Error') { $key = 'Last_SQL_Error'; } if (array_key_exists($key, $arStatus)) { $arStatus[$key] = $value; } } } } if ($bGlobalStatus) { $rs = $nodeDB->Query("show global status where Variable_name in ('Com_select', 'Com_do')", true, "", array("fixed_connection" => true)); if (is_object($rs)) { while ($ar = $rs->Fetch()) { if ($ar['Variable_name'] == 'Com_do') { $arStatus['Com_select'] -= $ar['Value'] * 2; } else { $arStatus['Com_select'] += $ar['Value']; } } } else { $rs = $nodeDB->Query("show status like 'Com_select'", false, "", array("fixed_connection" => true)); $ar = $rs->Fetch(); if ($ar) { $arStatus['Com_select'] += $ar['Value']; } $rs = $nodeDB->Query("show status like 'Com_do'", false, "", array("fixed_connection" => true)); $ar = $rs->Fetch(); if ($ar) { $arStatus['Com_select'] -= $ar['Value'] * 2; } } } } return $arStatus; }
if (is_array($arNode) && $arNode["GROUP_ID"] != $group_id && $arNode["ROLE_ID"] !== "MODULE") { $APPLICATION->AuthForm(GetMessage("ACCESS_DENIED")); } $aTabs = array(array("DIV" => "edit1", "TAB" => GetMessage("CLU_DBNODE_EDIT_TAB"), "ICON" => "main_user_edit", "TITLE" => GetMessage("CLU_DBNODE_EDIT_TAB_TITLE"))); $tabControl = new CAdminTabControl("tabControl", $aTabs); $ID = intval($ID); // Id of the edited record $strFatalError = ""; $strError = ""; $bVarsFromForm = false; if ($ID < 2) { if ($DB->type == "MYSQL") { $strFatalError = GetMessage("CLU_DBNODE_EDIT_ERROR"); } } else { $arNode = CClusterDBNode::GetByID($ID); if (!is_array($arNode)) { $strFatalError = GetMessage("CLU_DBNODE_EDIT_ERROR"); } elseif ($arNode["ROLE_ID"] == "SLAVE") { $strFatalError = GetMessage("CLU_DBNODE_EDIT_ERROR"); } } if ($strFatalError) { require $_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_admin_after.php"; ShowError($strFatalError); require $_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/epilog_admin.php"; } if ($REQUEST_METHOD == "POST" && check_bitrix_sessid()) { if ($save != "" || $apply != "") { $ob = new CClusterDBNode(); $arFields = array("ACTIVE" => $_POST["ACTIVE"], "SORT" => $_POST["SORT"], "NAME" => $_POST["NAME"], "DB_HOST" => $_POST["DB_HOST"], "DB_NAME" => $_POST["DB_NAME"], "DB_LOGIN" => $_POST["DB_LOGIN"], "DB_PASSWORD" => $_POST["DB_PASSWORD"], "DESCRIPTION" => $_POST["DESCRIPTION"]);
public static function SlaveNodeConnection($db_host, $db_name, $db_login, $db_password, $master_host = false, $master_port = false, $master_id = 1) { global $DB; $node_id = "v99"; CClusterDBNode::GetByID($node_id, array("ACTIVE" => "Y", "STATUS" => "ONLINE", "DB_HOST" => $db_host, "DB_NAME" => $db_name, "DB_LOGIN" => $db_login, "DB_PASSWORD" => $db_password)); ob_start(); $nodeDB = CDatabase::GetDBNodeConnection($node_id, true); $error = ob_get_contents(); ob_end_clean(); if (is_object($nodeDB)) { //Test if this connection is not the same as master //1. Make sure that no replication is runnung $rs = $nodeDB->Query("show slave status"); if ($ar = $rs->Fetch()) { if (strlen($ar["Slave_IO_State"]) > 0) { if ($ar["Master_Host"] != $master_host || $ar["Master_Port"] != $master_port) { return GetMessage("CLU_RUNNING_SLAVE"); } } } //2. Check if b_cluster_dbnode exists on node if ($nodeDB->TableExists("b_cluster_dbnode")) { //2.1 Generate uniq id $uniqid = md5(mt_rand()); $DB->Query("UPDATE b_cluster_dbnode SET UNIQID='" . $uniqid . "' WHERE ID=1", false, '', array("fixed_connection" => true)); $rs = $nodeDB->Query("SELECT UNIQID FROM b_cluster_dbnode WHERE ID=1", true); if ($rs) { if ($ar = $rs->Fetch()) { if ($ar["UNIQID"] == $uniqid) { return GetMessage("CLU_SAME_DATABASE"); } } } } //3. Check master connect if ($master_host !== false && $master_port !== false) { $node_id = "v98"; if ($master_id == 1) { CClusterDBNode::GetByID($node_id, array("ACTIVE" => "Y", "STATUS" => "ONLINE", "DB_HOST" => $master_host . ":" . $master_port, "DB_NAME" => $DB->DBName, "DB_LOGIN" => $DB->DBLogin, "DB_PASSWORD" => $DB->DBPassword)); } else { $node_id = $master_id; } ob_start(); $masterDB = CDatabase::GetDBNodeConnection($node_id, true); $error = ob_get_contents(); ob_end_clean(); if (is_object($masterDB)) { //3.1 Check if b_cluster_dbnode is the same as on master if (!$masterDB->TableExists("b_cluster_dbnode")) { return GetMessage("CLU_NOT_MASTER"); } //3.2 Generate uniq id $uniqid = md5(mt_rand()); $DB->Query("UPDATE b_cluster_dbnode SET UNIQID='" . $uniqid . "' WHERE ID=1", false, '', array("fixed_connection" => true)); $rs = $masterDB->Query("SELECT UNIQID FROM b_cluster_dbnode WHERE ID=1", true, '', array("fixed_connection" => true)); if (!$rs) { return GetMessage("CLU_NOT_MASTER"); } $ar = $rs->Fetch(); if (!$ar) { return GetMessage("CLU_NOT_MASTER"); } if ($ar["UNIQID"] != $uniqid) { return GetMessage("CLU_NOT_MASTER"); } } else { return GetMessage("CLU_MASTER_CONNECT_ERROR") . $error; } } return $nodeDB; } else { return $error; } }
/** * Creates a new slave connection. * * @return bool|null|Connection * @throws \Bitrix\Main\Config\ConfigurationException */ protected function createSlaveConnection() { if (!class_exists('csqlwhere')) { return null; } if (!Main\Loader::includeModule('cluster')) { return false; } $found = \CClusterSlave::GetRandomNode(); if ($found !== false) { $node = \CClusterDBNode::GetByID($found["ID"]); if (is_array($node) && $node["ACTIVE"] == "Y" && ($node["STATUS"] == "ONLINE" || $node["STATUS"] == "READY")) { $parameters = array('host' => $node["DB_HOST"], 'database' => $node["DB_NAME"], 'login' => $node["DB_LOGIN"], 'password' => $node["DB_PASSWORD"]); $connection = $this->cloneConnection(self::DEFAULT_CONNECTION_NAME, "node" . $node["ID"], $parameters); $connection->setNodeId($node["ID"]); return $connection; } } return false; }