【问题标题】:What are maintenance steps and performance steps for Mysql server/database?Mysql服务器/数据库的维护步骤和性能步骤是什么?
【发布时间】:2023-03-27 14:11:01
【问题描述】:

像索引维护一样,我们有索引重组/重建、更新统计信息、收缩数据库日志文件、数据库备份/恢复在 MS SQL 服务器中,Mysql 服务器/数据库的维护步骤和性能步骤是什么?

【问题讨论】:

    标签: sql tsql mysql phpmyadmin


    【解决方案1】:

    ANALYZE TABLE 将扫描键并存储有助于未来 JOIN 的数据。我不知道它实际上有多么有用/需要,但我敢打赌它肯定取决于您的典型数据库工作负载和表结构。

    OPTIMIZE TABLE 将对您的表进行碎片整理并回收未使用的空间,但正如您在文档中看到的那样,这通常是不必要的。

    您可以通过 SQL 或使用 mysqlcheck 工具调用它们。

    虽然大多数情况下没有必要,但我通常会在活动较少的时间安排mysqlcheck -Aao(这意味着在我的情况下是周末晚上)。

    【讨论】:

    • mysqlcheck -Aao ,我们如何安排它?
    【解决方案2】:
    //------------------------------------------------ -------------- //这是一个可以每周运行的 php 脚本。只需在开始时更改配置信息 //------------------------------------------------ -------------- //------------------------------------------------ -------------- // BEGIN CONFIG (我喜欢把它放在一个 sep 文件中,所以我可以改变配置 // 不同的数据库/服务器 //------------------------------------------------ -------------- //require_once ("mysql_maintenance_config.inc"); $_DB_Host = '127.0.0.1'; // 你的服务器ip $_DB_Name = 'database_name_goes_here'; // 要维护的数据库名称 $_DB_User = 'database_user_goes_here'; $_DB_Pass = 'password_goes_here'; $_EMAIL_Admin_Addr = '你的名字@gmail.com'; // 将错误/结果发送至电子邮件地址 // php邮件必须配置 $_LOG_TABLE_NAME = 'log_mysql_maintenance'; // 如果您希望将结果存储在不同的表名中,请更改此项 $_EMAIL_Results = 真; $_NO_WRITE_TO_BINLOG = 假; // 仅当数据库被复制时才设置为 true $_SKIP_TABLES_WITH_LESS_THAN_X_ROWS = 100; // 设置为 -1 以处理所有表 //------------------------------------------------ -------------- // 结束配置部分 //------------------------------------------------ -------------- $total_query_time_for_page = 0; $调试=假; //设置调试模式 if (isset($_GET['dxdb'])) { if ($_GET['dxdb']=='dcv') { $debug = true; } } // 打开数据库连接 $db = mysql_connect ($_DB_Host, $_DB_User, $_DB_Pass); 如果 (!$db) { 回声'DATABASE_ERROR_MESSAGE'; 出口; } if (mysql_select_db($_DB_Name, $db)==false) { 回声“CANNOT_SELECT_DATABASE”; 出口; } //------------------------------------------------ -------------- // MYSQL 维护任务 //------------------------------------------------ -------------- // 1. 验证/创建日志表 // 2. 初始化进程日志 // 3. 建表列表 // 4. 必要时检查和修复(仅限 MyISAM)表 // 5. 优化表格 // 6. 分析表格 // 7. 完整的日志和电子邮件 //------------------------------------------------ -------------- $_PROCESS_LOG = ''; $_PROCESS_ID = 0; $_STARTED_ON = ''; $_COMPLETED_ON = 0; $_TABLE_COUNT = 0; $_TABLES_CHECKED = 0; $_TABLES_OPTIMIZED = 0; $_TABLES_ANALYZED = 0; $_ERRORS_FOUND = 0; $_ERRORS_FIXED = 0; $_CURRENT_STATUS = ''; $_FINAL_STATUS = ''; //------------------------------------------------ -------------- // 1. 验证/创建日志表(sql_maintenance_config.php中设置的日志表名) //------------------------------------------------ -------------- $lgx = dbGetReturnForSQL("SELECT COUNT(*) as ct FROM information_schema.tables WHERE table_schema = '$_DB_Name' AND table_name = '$_LOG_TABLE_NAME'",'',true); if ($lgx==0) // 创建日志表 { $sql = "创建表 $_LOG_TABLE_NAME ( process_id int(11) NOT NULL auto_increment, started_on varchar(24) NOT NULL default '', completed_on varchar(24) NOT NULL default '', tables_checked int(11) NOT NULL 默认 0, tables_optimized int(11) NOT NULL 默认 0, tables_analyzed int(11) NOT NULL 默认 0, errors_found int(11) NOT NULL 默认 0, errors_fixed int(11) NOT NULL 默认 0, current_status varchar(32) NOT NULL default '', final_status varchar(32) NOT NULL default '', process_log varchar(20000) NOT NULL default '', 主键 (process_id) ) 引擎=InnoDB AUTO_INCREMENT=1 默认字符集=utf8"; dbExecuteSQL($sql); $_PROCESS_LOG = "首次运行 - 创建日志记录表\n -------------------------------------- ------------ \n"; } 别的 { $_PROCESS_LOG = "日志表正常 - 开始进程\n -------------------------------------- ------------ \n"; } //------------------------------------------------ -------------- // 2. 初始化进程日志 //------------------------------------------------ -------------- $_STARTED_ON = getLogStamp(); $_CURRENT_STATUS = '初始化进程日志'; $_FINAL_STATUS = '处理中 - 没有错误'; $sql = "INSERT INTO $_LOG_TABLE_NAME (started_on, current_status, final_status, process_log) VALUES ('$_STARTED_ON', '$_CURRENT_STATUS', '$_FINAL_STATUS', '$_PROCESS_LOG')"; $_PROCESS_ID = dbExecuteSQL($sql, true); add2ProcessLog('初始化进程日志', true); 如果($_NO_WRITE_TO_BINLOG) { $_BINLOG = 'NO_WRITE_TO_BINLOG'; add2ProcessLog('BINLOG WRITE DISABLED'); } 别的 { $_BINLOG = ''; add2ProcessLog('BINLOG WRITE ENABLED'); } //------------------------------------------------ -------------- // 3. 建表列表 //------------------------------------------------ -------------- $_CURRENT_STATUS = '构建表列表'; add2ProcessLog('建表列表', true); $sql = "选择表名、引擎、表行 FROM information_schema.tables WHERE table_schema = '$_DB_Name'"; $_TABLE_LIST = dbGetReturnForSQL($sql); if ($_TABLE_LIST == 'x_no_data_x') // 没有找到表 { add2ProcessLog("错误 - 没有找到表", false); emailLogAndExit(); } 别的 { $_TABLE_COUNT = 计数($_TABLE_LIST); add2ProcessLog($_TABLE_COUNT . " 找到表", true); } //------------------------------------------------ -------------- // 4. 必要时检查和修复(仅限 MyISAM)表 //------------------------------------------------ -------------- $_CURRENT_STATUS = '检查并修复 MYISAM 表'; add2ProcessLog("检查并修复 MISAM 表", true); foreach($_TABLE_LIST AS $tbl_row) { $tbl = $tbl_row['TABLE_NAME']; $eng = $tbl_row['ENGINE']; $rct = $tbl_row['TABLE_ROWS']; if ($tbl != $_LOG_TABLE_NAME && $eng == 'MyISAM') { $_TABLES_CHECKED++; add2ProcessLog("检查:$tbl"); $sql = "检查表 $tbl"; $rs = dbGetReturnForSQL($sql); if ($rs == 'x_no_data_x') { emailLogAndExit("错误检查表:$tbl"); } 别的 { $rw = getLastRecord($rs); if ($rw['Msg_text'] != 'OK') { $_ERRORS_FOUND++; add2ProcessLog('发现错误:' . $rw['Msg_text'], true); // 问题检查表 - 尝试修复 $sql = "修复表 $tbl"; $rs = dbGetReturnForSQL($sql); if ($rs == 'x_no_data_x') { emailLogAndExit("错误修复表:$tbl"); } 别的 { $rprw = getLastRecord($rs); if ($rw['Msg_text'] == 'OK') { $_ERRORS_FIXED++; add2ProcessLog('错误修复' . $tbl); } else //无法修复错误 { emailLogAndExit("错误修复表:$tbl | " . $rw['Msg_text']); } } } 别的 { add2ProcessLog($tbl . '检查好'); } } } } add2ProcessLog("检查并修复MYISAM 表已完成", true); //------------------------------------------------ -------------- // 5. 优化表格 //------------------------------------------------ -------------- $_CURRENT_STATUS = '优化表'; add2ProcessLog("优化表", true); foreach($_TABLE_LIST AS $tbl_row) { $tbl = $tbl_row['TABLE_NAME']; $eng = $tbl_row['ENGINE']; $rct = $tbl_row['TABLE_ROWS']; if ($tbl != $_LOG_TABLE_NAME && intval($_SKIP_TABLES_WITH_LESS_THAN_X_ROWS) '千斤顶函数', '//#_reason_//#' => '因为我这么说') // $new_page: 如果为真,清除缓冲区并换入新页面,如果为假,则显示错误消息并退出(注意,要使用此功能,必须先在页面上调用 ob_start() // $dev_dump: 任何你想要在日志中的杂项信息,例如导致错误的查询。这不会显示给用户 // $email_err:发送错误的电子邮件地址。如果设置为“devteam”,则将使用当前组邮件地址(即 devteam@thinklinklearning.com) // 未来 - 可能想要在 error_codes 表中设置一种方法来覆盖它,以便在测试期间发送给特定的开发人员(目前只能覆盖为始终发送电子邮件) // $log_only: 如果为 true,则不显示消息,返回代码 - 如果我们想从 perish() 记录到这里,可以使用 全局 $db,$_EMAIL_Admin_Addr,$_CURRENT_STATUS,$_FINAL_STATUS; // 首先记录错误 $host_info = mysql_get_host_info(); $rq = substr(var_export($_REQUEST,true),0,2000); $rq = mysql_real_escape_string($rq); // 将最后一个 sql 错误附加到 dev_dump $sql_dump = $dev_dump; //格式化sql $sql_dump = str_replace("\r\n",'',$sql_dump); $sql_dump = str_replace("\n",'',$sql_dump); $sql_dump = str_replace("\t",'',$sql_dump); $sql_dump = str_ireplace('SELECT',"\r\n SELECT",$sql_dump); $sql_dump = str_ireplace('FROM',"\r\n FROM",$sql_dump); $sql_dump = str_ireplace('WHERE',"\r\n WHERE",$sql_dump); $sql_dump = str_ireplace('INNER JOIN',"\r\n INNER JOIN",$sql_dump); $sql_dump = str_ireplace('LEFT JOIN',"\r\n LEFT JOIN",$sql_dump); $sql_dump = str_ireplace('AND',"\r\n AND",$sql_dump); $sql_dump = str_ireplace('GROUP BY',"\r\n GROUP BY",$sql_dump); $sql_dump = str_ireplace('ORDER BY',"\r\n ORDER BY",$sql_dump); $sql_dump = str_ireplace(',',"\r\n, ",$sql_dump); $sql_dump = str_replace(' ',' ',$sql_dump); $sql_dump = str_replace(' ',' ',$sql_dump); $sql_dump = str_replace(' ',' ',$sql_dump); $sql_err = mysql_error(); $dev_dump = $sql_dump 。 "\r\n\r\n" 。 $sql_err; //echo "
    $sql_err
    $sql_dump
    "; $dev_dump_to_mail = $host_info 。 "\r\n\r\n" 。 $dev_dump; $dev_dump = mysql_real_escape_string($dev_dump_to_mail . "\r\n\r\n" . $dev_dump); // 获取堆栈回溯 $a = debug_backtrace(); $stack_tr = "堆栈跟踪:\r\n"; $stack_tr .= "------------ \r\n"; foreach($a as $k => $v) { $stack_tr .= "文件:$v[文件] \r\n"; $stack_tr .= "行:$v[行] \r\n"; $stack_tr .= "func: $v[函数] \r\n"; $args = $v['args']; foreach($args as $a_label => $a_val) { $stack_tr .= "$a_label => $a_val \r\n"; } $stack_tr .= "//# \r\n"; } $pg = mysql_real_escape_string($_SERVER['PHP_SELF']); $stack_tr_to_mail = $stack_tr; $stack_tr = mysql_real_escape_string($stack_tr); if ($err_id=='') { $err_id = 'GENERAL_ERROR'; } $email_err = $_EMAIL_Admin_Addr; // 总是通过电子邮件将错误发​​送给管理员 $err_html = ''; // 如果请求,电子邮件错误 if ($email_err!='') { $pg = explode('/', $pg); $pg = $pg[计数($pg)-1]; if (strpos(strtoupper($_SERVER['SERVER_NAME']),'DEV')>2) { $fsrv = '(DEV)'; } 其他 { $fsrv = ''; } 邮件($email_err,“错误$fsrv:$pg - $err_id”, "PHP_SELF\t $_SERVER[PHP_SELF] \n\n------------------------------------\n\n error_id:\t $err_id\n\n \n\n------------------------------------\n\n sql_err:\t $sql_err \n\n \n\n------------------------------------\n\n sql_dump:\n\n $sql_dump \n\n \n\n------------------------------------\n\n last_db_host:\t $host_info\n\n \n\n------------------------------------\n\n stack_tr:\n $stack_tr_to_mail\n\n \n\n------------------------------------\n\n 开发转储:\n $dev_dump_to_mail\n\n \n\n------------------------------------\n\n err_log_key: $err_log_key "); } // 更新进程日志 $_CURRENT_STATUS = '错误'; $_FINAL_STATUS = '错误'; add2ProcessLog('ERROR - ' . $sql_err, true); 回声“错误:”。 $pg 。 '-'。 $sql_err; 出口(); } //------------------------------------------------ -------------- 函数 getRequestVar($fieldname,$defaultvalue,$numeric_only=false,$prep_for_sql_insert=false) { $rtn = ''; if (isset($_POST[$fieldname])) { $rtn = $_POST[$fieldname]; } 别的 { if (isset($_GET[$fieldname])) { $rtn = $_GET[$fieldname]; } 别的 { $rtn = $默认值; } } if ($numeric_only==true) { if (is_numeric($rtn)==false) {$rtn = $defaultvalue;} } 如果($prep_for_sql_insert==true) { $rtn = "'" 。 mysql_real_escape_string($rtn) 。 "'"; } 返回($rtn); } //------------------------------------------------ -------------- 函数 prepForSQL($rtn_val, $numeric_only=false) { if ($numeric_only==true) { if (is_numeric($rtn_val)==false) {$rtn_val = -999;} } 别的 { // 删除系统中不允许的 chrs $rtn_val = str_replace("'","",$rtn_val); $rtn_val = str_replace('"',"",$rtn_val); $rtn_val = str_replace("\\","",$rtn_val); $rtn_val = str_replace(';',"",$rtn_val); $rtn_val = "'" 。 mysql_real_escape_string($rtn_val) 。 "'"; } 返回($rtn_val); } //------------------------------------------------ -------------- 函数 dbGetReturnForSQL($sql, $field_for_key = '', $get_scalar_value = false, $default_value = 'x_no_data_x') { /* 此函数适用于标量、单行和多行查询 如果 $field_for_key = '' 然后使用索引 如果 $get_scalar_value = true 则仅返回数组中的第一行(不嵌套在行数组中)或仅返回 1 个值(无数组) - 仅第一行必须设置为 true 如果不存在数据,则返回 $default_value,如果为空,则返回 'x_no_data_x' $error_id_on_fail,传递给 displayErrorMsg 的错误 ID(默认为 GENERAL_ERROR) */ 全局 $db, $debug, $total_query_time_for_page; $loc_ptr = 0; $loc_key = ''; $loc_arr = 数组(); $loc_val = ''; $use_srv = '大师'; $error_id_on_fail = ''; 如果($调试){ echo "
    QUERY:

    \n
    \n" 。 ereg_replace("\t", " ", $sql) 。 "\n
    \n

    \n"; } if ( $debug ) { $start_time = microtime(true); } $result = mysql_query($sql,$db) OR displayErrorMsg($error_id_on_fail,'','',false,$sql,'richard.varno@gmail.com',false); 如果($调试) { $end_time = 微时间(真); $rows_rtn = mysql_num_rows($result); $qry_time = $end_time - $start_time; $total_query_time_for_page = $total_query_time_for_page + $qry_time; $host_info = mysql_get_host_info(); echo "$rows_rtn 行在 $qry_time 秒内从 $host_info ($use_srv) 返回

    总查询时间:$total_query_time_for_page 秒

    \n"; } 而 ($rw = mysql_fetch_assoc($result)) { if ($get_scalar_value==true) { // 如果 debug = true 则显示返回值 如果($调试) { echo "标量值
    \n\n"; foreach($rw 作为 $fld_key => $fld_val) { echo "$fld_key$fld_val\n"; } 回声“\n”; } 如果(计数($rw)==1) { $rw_key = array_keys($rw); $loc_val = $rw[$rw_key[0]]; mysql_free_result($result); 返回($loc_val); } 别的 { mysql_free_result($result); 返回($rw); } } 别的 { if ($field_for_key=='') //使用索引指针 { $loc_key = $loc_ptr; } 否则 // 使用字段 { $loc_key = $rw[$field_for_key]; } $loc_arr[$loc_key] = $rw; $loc_ptr++; } } mysql_free_result($result); // 如果没有找到结果,返回默认值 如果 ($loc_ptr == 0) { $loc_arr = $default_value; } 别的 { // 如果 debug = true 则显示返回值(仅限第 50 行) 如果($调试) { 如果($rows_rtn > 50) { echo "显示$rows_rtn的第1行到$rows_rtn
    \n"; $max_row_to_display = 49; } 别的 { echo "显示$rows_rtn的第1行到$rows_rtn
    \n"; $max_row_to_display = $rows_rtn-1; } 回声“\n”; // 显示标题 $loc_arr_keys = array_keys($loc_arr); $rw = $loc_arr[$loc_arr_keys[0]]; 回声“\n”; foreach($rw 作为 $fld_key => $fld_val) { echo "$fld_key\n"; } 回声“\n”; // 显示数据 $cur_row = 0; foreach ($loc_arr as $ptr=>$row) { 回声“\n”; foreach($rw 作为 $fld_key => $fld_val) { echo "$row[$fld_key]\n"; } 回声“\n”; $cur_row++; if ($cur_row > $max_row_to_display) { 休息; } } 回声“\n”; } } 返回($loc_arr); } //------------------------------------------------ -------------- 函数 dbExecuteSQL($sql, $return_insert_id = false) { /* 此函数将针对主数据库执行 SQL 语句,并在请求时返回受影响的行或插入 id $error_id_on_fail,传递给 displayErrorMsg 的错误 ID(默认为 GENERAL_ERROR) */ 全局 $db, $debug, $total_query_time_for_page; $loc_ptr = 0; $loc_insert_id = 0; $loc_rows_affected = 0; $error_id_on_fail = ''; 如果($调试){ echo "
    QUERY:


    \n
    \n" 。 ereg_replace("\t", " ", $sql) 。 "\n
    \n

    \n"; } if ( $debug ) { $start_time = microtime(true); } $result = mysql_query($sql,$db) OR displayErrorMsg($error_id_on_fail,'','',false,$sql,'richard.varno@gmail.com',false); $loc_insert_id = mysql_insert_id($db); $loc_rows_affected = mysql_affected_rows($db); $use_srv = '大师'; 如果($调试) { $end_time = 微时间(真); $qry_time = $end_time - $start_time; $total_query_time_for_page = $total_query_time_for_page + $qry_time; $host_info = mysql_get_host_info($db); echo "$host_info ($use_srv) 在 $qry_time 秒内受影响的 $loc_rows_affected 行

    总查询时间:$total_query_time_for_page 秒

    \n"; } if ($return_insert_id==true) { return($loc_insert_id); } 其他 { 返回($loc_rows_affected); } } //------------------------------------------------ --------------

    【讨论】:

      猜你喜欢
      • 2010-10-08
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 2017-05-17
      • 1970-01-01
      相关资源
      最近更新 更多