mysql expire_logs_days是怎麼生效和計算出來的
mysql主備複製是透過binlog完成的。在開啟binlog的情況下,expire_logs_days引數可以讓mysql自動清理若干天前的binlog。
那麼expire_logs_days是在什麼時候生效的呢?初步猜想實在每次產生一個新的binlog的時候去判斷一次。查了一下具體的實現,確實是這樣的:
原始碼(5.1.58, log.cc)
int MYSQL_BIN_LOG::rotate_and_purge(uint flags)
{
...
if (!error && check_purge && expire_logs_days)
{
time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
if (purge_time >= 0)
purge_logs_before_date(purge_time);
}
...
}
如果設定了expire_logs_days,每次binlog rotate的時候都去計算一下purge_time(當前時間-expire_logs_days;
這個計算似乎是可以省去的: expire_logs_days是以天為單位,範圍是0~99, 0表示不會清理,自然不會進入if塊內:),
以99來計算,my_time(0) - 99*24*60*60>=0也是恆真的了),呼叫purge_logs_before_date(purge_time),
purge_logs_before_date會從log index檔案中的第一個binlog檔案開始迴圈: 比較檔案的最後修改時間,如果小於purge_time,
就放入陣列to_log中。然後呼叫purge_logs,清理所有滿足條件的binlog。
int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
{
...
MY_STAT stat_area;
...
pthread_mutex_lock(&LOCK_index);
to_log[0]= 0;
if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
goto err;
while (strcmp(log_file_name, log_info.log_file_name) &&
!is_active(log_info.log_file_name) &&
!log_in_use(log_info.log_file_name))
{
...
if (stat_area.st_mtime < purge_time)
strmake(to_log,
log_info.log_file_name,
sizeof(log_info.log_file_name) - 1);
else
break;
...
}
下面看一下purge_logs的實現:
int MYSQL_BIN_LOG::purge_logs(const char *to_log,
bool included,
bool need_mutex,
bool need_update_threads,
ulonglong *decrease_log_space)
{
...
while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
!is_active(log_info.log_file_name) &&
!log_in_use(log_info.log_file_name))
{
if ((error= register_purge_index_entry(log_info.log_file_name)))
...
}
...
/* We know how many files to delete. Update index file. */
if ((error=update_log_index(&log_info, need_update_threads)))
...
/* Read each entry from purge_index_file and delete the file. */
if (is_inited_purge_index_file() &&
(error= purge_index_entry(thd, decrease_log_space, FALSE)))
...
purge_logs會將需要清理的binlog檔名放入purge_index_file(IO_CACHE)中,然後更新index檔案,最後再呼叫purge_index_entry刪除binlog檔案:
int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
bool need_mutex)
{
...
for (;;)
{
...
if (!my_delete(log_info.log_file_name, MYF(0)))
{
if (decrease_log_space)
*decrease_log_space-= s.st_size;
}
...
}
my_delete呼叫unlink()刪除binlog檔案。至此,完成了自動清理binlog的過程。另外當mysql啟動的時候,mysql也會執行purge_logs_before_date(purge_time)的過程(其它的操作,如果會引起binlog rotate,自然也會觸發這個過程,如flush logs)。
梳理一下整個過程,不難發現,在壓力比較大的mysql上或生產環境,我們不應該啟動這個引數(my.cnf中不顯式設定該引數或設定expire_logs_days=0):mysql每天產生十幾個或更多的binlog檔案,啟用這個引數後,一次清理這麼多檔案,必定會導致磁碟io被佔滿,mysql出現抖動或hang住。因此建議自己編寫指令碼,每次purge完一個binlog後,sleep幾秒。
注意:
expire_logs_days設定之後不會立即清除,觸發條件是:
binlog大小超過max_binlog_size
手動執行flush logs
重新啟動時
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15498/viewspace-2220393/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- One Order行專案裡Item Category是怎麼計算出來的Go
- 為什麼milvus 計算出來的歐式距離和實際不符合?
- Linux 中 CPU 利用率是如何算出來的?Linux
- 年利率、月利率、日利率究竟是怎麼算出來的?
- 企業伺服器租用價格究竟是怎麼算出來的呢伺服器
- 大佬是怎麼思考設計MySQL優化方案的?MySql優化
- mysql order by是怎麼工作的?MySql
- 你來寫,“Calca”來快速算出計算結果
- C#是怎麼跑起來的C#
- 完蛋,我的事務怎麼不生效?
- MySQL 的 NULL 值是怎麼儲存的?MySqlNull
- 計算機是怎樣跑起來的計算機
- 股票收益率的協方差矩陣算出來有什麼用矩陣
- # MySQL server 層和儲存引擎層是怎麼互動資料的?MySqlServer儲存引擎
- 方法分享|怎樣算出3d下期和值T3D
- 大家是怎麼程式設計的程式設計
- DHCP和PXE是怎麼工作的
- 計算出大小有什麼走勢圖規律
- 屏保設定不生效怎麼做?
- 指紋登入是怎麼跑起來的
- 什麼是 SRE?它和 DevOps 是怎麼關聯的?dev
- 《程式是怎樣跑起來的》讀書筆記1——對程式設計師來說CPU是什麼筆記程式設計師
- MySQL5.7和MySQL8.0的區別是什麼?MySql
- MySQL是怎麼解決幻讀問題的?MySql
- 根據設計稿,計算出網頁REM的大小,有那麼難嗎?網頁REM
- 程式是怎麼跑起來的第七章
- 程式是怎麼跑起來的第二章
- 程式是怎麼跑起來的第五章
- 運維知識是怎麼構建起來的運維
- 領導駕駛艙是怎麼做出來的?
- 你真的知道協程是怎麼來的嗎?
- MYSQL查詢和插入資料的流程是怎樣的MySql
- win10更改完環境變數怎麼生效 windows10怎麼讓環境變數生效Win10變數Windows
- inject 不生效?!依賴注入背後的實現原理和執行邏輯是怎樣的?依賴注入
- 你來講講AQS是什麼吧?都是怎麼用的?AQS
- txt是什麼格式的檔案 txt格式怎麼弄出來
- Google 是怎麼設計遊戲手柄的?Go遊戲
- 和 koa 不同的 express 是怎麼實現Express