天天看點

通過python備份sql server資料庫

通過python備份sql server資料庫

任務背景:

年前我們的資料庫遭到了勒索病毒的襲擊,咨詢了360安全工程師,伺服器中的師Globelmposter家族的勒索病毒,目前沒有辦法進行解密,建議一旦發現伺服器中了勒索病毒後,第一時間斷網,避免其他伺服器也感染,大家可以百度下這個病毒,太狂妄了。可憐的是我們的伺服器還沒有備份機制,伺服器分布較散,前期沒有做備份規劃。現在提出來了要對伺服器上面的資料進行備份。

備份思路:

由于沒有多出來的伺服器,加上項目分散,伺服器分散等特點,再加上我們使用的是windows server伺服器。利用現有資源,終于想出來一個叫做三角備份的異地容災備份方式

三角備份:簡單來說就是A地區伺服器上面的資料備份到B地區伺服器上,B地區伺服器上面的資料備份到C地區的伺服器上,然後C地區的伺服器上面的資料備份到A地區伺服器上

實施準備

資料庫相關準備資訊

1、連接配接資料庫。

這裡的賬号密碼一會要用的
通過python備份sql server資料庫

2、檢視資料庫連接配接相關資訊,有用

提示:一定要在資料庫連接配接成功并且可以正常操作資料庫的時候,再擷取連接配接資訊,否則在腳本中報錯了,都不知道是什麼原因。
通過python備份sql server資料庫
通過python備份sql server資料庫

擷取資料庫執行個體名

如果有十足的把握的話,可以不看這個執行個體名
通過python備份sql server資料庫

3、對相應的執行個體名開啟一會我們腳本中要用到的tcp動态端口,不開啟這個tcp動态端口,腳本沒法運作

開啟之後要記得這個動态端口,端口号自己随意,不要與其他的程式沖突就行,建議号值大點

打開sql server配置管理器,可以自己找找,如下圖,我的位置在

通過python備份sql server資料庫
通過python備份sql server資料庫
通過python備份sql server資料庫
通過python備份sql server資料庫

腳本所需要的配置檔案,日志以及目錄

由于備份的資料庫較多,腳本不可能寫成闆磚,是以自己給腳本加了一個配置檔案,通過讀取配置檔案來實作對不同的資料庫進行備份

還有就是日志,排錯主要靠日志,這裡自己也沒有使用python的log子產品,自己寫了一個log函數,簡單明了的告訴自己腳本都幹了些什麼

通過python備份sql server資料庫

下圖需要注意的事項:

1、host為資料庫所在位址,建議在本機上用127.0.0.1

2、port這個就是咱設定的那個tcp動态端口

3、其他的選項自己看着來吧

通過python備份sql server資料庫
通過python備份sql server資料庫
通過python備份sql server資料庫
通過python備份sql server資料庫

直接上代碼解釋

鬼見愁除了長的帥之外,人也好,關鍵是不羅嗦,直接開始
#mdir_time=2021-02-20
#to backup database
# 主要實作備份wei資料庫,到目前目錄下面的database_backup目錄下面,備份檔案為wei.bak
# 關鍵性資料庫備份指令:Backup Database wei To disk='E:\python2\database_backup\wei.bak'

import configparser
import pymssql
import os
import datetime
import time

#配置目前時間
#由于這個腳本隻是其一,單單的進行本地備份,
#腳本為後期超過30天自動删除和用python實作跨網絡的windows server伺服器之間的檔案傳輸做準備

time1 = str(datetime.datetime.now())
time2 = time1.split('.')[0]
time3 = time2.split(' ')[0]

#該腳本所需要的配置檔案、日志和備份目錄的路徑,友善建立
#這個腳本有自己的配置檔案和日志展示
current_path = os.getcwd()
current_config_path = current_path + '\\' + 'config.ini'
current_log_path = current_path + '\\' + 'log.txt'
current_database_backup_path = current_path + '\\' + 'database_backup'

#判斷配置檔案.ini和日志檔案是否存在,沒有則建立
def path_txt_judge(txt):
    if os.path.exists(txt):
        print(time2, '    '+txt+'已存在,不需要建立')
        file = open(current_log_path, 'a', encoding='utf-8')
        #    file.write('hello\nword')
        a = str(time2 + "    "+txt+"檔案存在")
        # print(a)
        file.write(a + "\n")
        file.close()
    else:
        file = open(txt, 'a', encoding='utf-8')  # a 的話是追加寫入,不覆寫之前的内容
        a1 = str(time2 + '    建立'+txt+'檔案' + current_log_path + '成功')
        file.write(a1 + "\n")
        file.close()
        
#判斷backup目錄是否存在,不存在則建立
#為什麼要指定目錄呢,因為後期咱上傳到别的服務的時候能第一時間找到備份檔案
def path_dir_judge(dir):
    if os.path.exists(dir):
        print(time2, '    檔案目錄存在,不需要建立')
        file = open(current_log_path, 'a', encoding='utf-8')  # w 的含義為可進行讀寫
        #    file.write('hello\nword')
        d = str(time2 + '    備份目錄' + current_database_backup_path + '存在')
        file.write(d + "\n")
        file.close()
    else:
        os.makedirs(dir)
        file = open(current_log_path, 'a', encoding='utf-8')  # w 的含義為可進行讀寫
        #    file.write('hello\nword')
        d1 = str(time2 + '    備份目錄' + current_database_backup_path + '建立成功')
        file.write(d1 + "\n")
        file.close()
        
# 主要實作了一個對日志檔案的寫,非常清晰明了的告訴自己都幹了些什麼
def log_write(log):
    file = open(current_log_path, 'a', encoding='utf-8')  # w 的含義為可進行讀寫
    file.write(log + "\n")
    file.close()
    
#調用相應的函數
path_txt_judge(current_log_path)
path_txt_judge(current_config_path)
path_dir_judge(current_database_backup_path)

#對配置檔案config.ini進行讀取,擷取所需要的資料
cf= configparser.ConfigParser()
cf.read(current_config_path)
database_host = cf.get('sql_server','host')  #得到hose
database_port = cf.get('sql_server','port')  #得到端口号
database_user = cf.get('sql_server','user')  #得到登入資料的使用者名
database_password = cf.get('sql_server','password')  #得到登入資料庫的密碼
backup_database = cf.get('database_name','database_name') #得到你想要備份的資料庫名稱

#連接配接資料庫,執行備份操作
conn = pymssql.connect(host=database_host,port=database_port,user=database_user,password=database_password)
if conn:
    print(time2,"    連接配接資料庫",database_host,"成功!")
    e = str(time2 + '    連接配接資料庫' + database_host + '成功')
    log_write(e)
else:
    print(time2,"    連接配接資料庫",database_host,"沒有成功! 請仔細檢查防火牆、資料庫tcp/ip動态端口是否開啟或者配置檔案配置是否正确")
    e1 = str(time2 + '    連接配接資料庫' + database_host + '出現問題,請仔細檢查防火牆、資料庫tcp/ip動态端口是否開啟或者配置檔案配置是否正确')
    log_write(e1)
    time.sleep(5)

conn.autocommit(True)
cursor = conn.cursor()
backup_sql_path = current_database_backup_path+"\\"+time3+"_"+backup_database+".bak"

sql = "Backup Database " +backup_database+" To disk="+'\''+backup_sql_path+'\''
cursor.execute(sql)
sql1 = str("Backup Database " +backup_database+" To disk="+'\''+backup_sql_path+'\'')
f2 = str(time2 + '    對資料庫執行備份操作'+'備份語句為:'+sql1)
print(time2,'    正在對資料庫進行備份操作,請稍等...')
log_write(f2)
conn.commit()   #這個送出動作比較重要
time.sleep(10)


#斷開與資料庫的連接配接
conn.close()
print(time2,"    已斷開與資料庫",database_host,"的連接配接!")
time.sleep(10)
f1 = str(time2 + "    已斷開"+database_host+'資料庫的連接配接!')
log_write(f1)
           

結束語

下篇将展示python實作跨網絡的實作windows server服務之間的備份檔案傳輸

熬夜,隻是為了明天可以抽根好煙