MySQL 刪除大量資料的具體實現

2021-09-23 21:04:35 字數 3451 閱讀 5869

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...