ourmysql部落格中提供了 《
大表刪除資料的思路
》,對於大表依據主鍵刪除的思路是必須的,刪除幾千萬的資料還算是比較簡單的,如果你的資料庫中的表高達數百億條記錄 ,刪除其中的幾十億,就需要考慮可用性的問題了。上述文中的 利用生成的文字方式有些不妥。
我的方法是利用儲存過程,游標,先根據條件獲取要刪除的主鍵,然後依據主鍵刪除,考慮到刪除50億條記錄耗費將近7天的時間(事後得出),必須後台執行。使用python 工具寫乙個指令碼,可以針對多個伺服器進行並行操作。
1 在各個伺服器上建立存過!
delimiter //
create procedure `proc_del_tab`(in com_num int , in push_time datetime )
begin
declare curid bigint ;
declare rowid bigint ;
declare no_more_departments int ;
declare curs cursor for
select id
from
tabwhere
v3 < push_time ;
declare continue handler for not found set no_more_departments = 1;
set no_more_departments=0;
set rowid = 1 ;
set autocommit = 0 ;
open curs ;
repeat
fetch curs into curid ;
delete from tab where id = curid ;
set rowid = rowid + 1 ;
if rowid % com_num = 0
then
commit;
end if ;
until no_more_departments
end repeat;
commit ;
close curs ;
end; //
delimiter ;
2 部署python 指令碼:
#!/usr/bin/env python
from mysqldb import *
import sys
import threading
import time
import os
def now() :
#return str('2011-01-31 00:00:00')
return str( time.strftime( '%y-%m-%d %h:%m:%s' , time.localtime() ) )
def log( strs , logs ) :
f = file( logs , 'a' , 0 )
f.write( now() + ' ' + str(strs) + '\n' )
f.close()
def delining( cur , logs ) :
sql = "set sql_log_bin=0"
try :
cur['dsn'].execute( sql )
except exception , e :
log( 'set sql_log_bin off' + str(e) , logs )
sql = "call proc_del_tab_yang( 3000 , '%s' )" % ('2011-01-31 00:00:00')
log( 'starting process %s' % ( cur['addr'] ) , logs )
try :
cur['dsn'].execute( sql )
except exception , e :
log( 'execute procedure ' + str(e) , logs )
sql = "set sql_log_bin=1"
try :
cur['dsn'].execute( sql )
except exception , e :
log( 'set sql_log_bin on' + str(e) , logs )
log( 'process %s end' % ( cur['addr'] ) , logs )
def main() :
logs = "/root/yangql/python/del_test_tab.log"
server_list=['10.250.7.110']
luser="yang"
lpasswd="yang"
con =
for addr in server_list :
cons = none
try :
except exception , e :
log( 'on connect %s ' % ( addr ) + str(e) , logs )
continue
cur =
for cons in con :
try :
except exception , e :
log( 'on cusros %s ' % ( cons['addr'] ) + str(e) , logs )
continue
thpool =
for curs in cur :
th = threading.thread(target = delining ,args=( curs , logs ) )
for th in thpool :
th.start()
for th in thpool :
threading.thread.join( th )
while true :
if threading.activecount() < 2 :
break
else :
time.sleep(1)
continue
for curs in cur :
try :
curs['dsn'].close()
except exception , e :
log( 'on close cusros %s ' % ( curs['addr'] ) + str(e) , logs )
continue
for cons in con :
try :
cons['dsn'].close()
except exception , e :
log( 'on close connect %s ' % ( str(e) ) , logs )
continue
if __name__ == '__main__' :
main()
mysql大量資料刪除
近期有一張表,存量有3000多萬資料,每天還在以40萬左右增長。業務上準備只保留兩個月的資料。準備刪除。這個量直接刪除,可能會導致鎖表。要麼寫個儲存過程,迴圈,每次刪除1000條,sleep下。當然這個方法很不錯。但delete是dml語言,刪除只是把狀態標記為刪除,並沒有刪除資料檔案,也就是空間索...
mysql刪除大量資料
mysql刪除大量資料時使用批量刪除,批量刪除時,不要使用排序,會影響刪除效率 delete from table name where id 66169770 limit 1000000 以下資料摘自 生產環境,往往需要更新 刪除大量的資料,由於很可能消耗太多的io資源,對於生產繁忙的系統,需要小...
MySql刪除大量資料
再介紹刪除解決方案前,先來回顧下三種刪除表的操作 delete語句 truncate語句以及drop語句。drop truncate delete 下面說下刪除大量資料的解決方案 delete from t test limit 100000或者建立儲存過程 delimiter drop proce...