zoukankan      html  css  js  c++  java
  • mysql-schema-sync 实现 不同环境实例间表结构统一

     

    需求:dev,test,release环境由于权限没有统一收管,很容易引起数据库表结构不一致情况;分享一个简单实用易上手的小工具;

    mysql-schema-sync:

    支持功能:

    1. 同步新表
    2. 同步字段 变动:新增、修改
    3. 同步索引 变动:新增、修改
    4. 支持预览(只对比不同步变动)
    5. 邮件通知变动结果
    6. 支持屏蔽更新表、字段、索引、外键
    7. 支持本地比线上额外多一些表、字段、索引、外键

    安装:

    go get -u github.com/hidu/mysql-schema-sync

    参考 默认配置文件 config.json 配置同步源、目的地址。
    修改邮件接收人 当运行失败或者有表结构变化的时候你可以收到邮件通知。

    默认情况不会对多出的表、字段、索引、外键删除。若需要删除字段、索引、外键 可以使用 -drop 参数。

    配置示例(config.json):

    {
          //source:同步源
          "source":"test:test@(127.0.0.1:3306)/test_0",
          //dest:待同步的数据库
          "dest":"test:test@(127.0.0.1:3306)/test_1",
          //alter_ignore: 同步时忽略的字段和索引
          "alter_ignore":{
            "tb1*":{
                "column":["aaa","a*"],
                "index":["aa"],
                "foreign":[]
            }
          },
          //  tables: table to check schema,default is all.eg :["order_*","goods"]
          "tables":[],
          //有变动或者失败时,邮件接收人
          "email":{
              "send_mail":false,
             "smtp_host":"smtp.163.com:25",
             "from":"xxx@163.com",
             "password":"xxx",
             "to":"xxx@163.com"
          }
    }

    json配置项说明

    source: 数据库同步源
    dest: 待同步的数据库
    tables: 数组,配置需要同步的表,为空则是不限制,eg: ["goods","order_*"]
    alter_ignore: 忽略修改的配置,表名为tableName,可以配置 column 和 index,支持通配符 *
    email : 同步完成后发送邮件通知信息

    直接运行

    mysql-schema-sync -conf mydb_conf.json -sync

    预览并生成变更sql

    mysql-schema-sync -conf mydb_conf.json 2>/dev/null >db_alter.sql

    使用shell调度

    bash check.sh

    每个json文件配置一个目的数据库,check.sh脚本会依次运行每份配置。 log存储在当前的log目录中。

    自动定时运行

    添加crontab 任务

    30 * * * * cd /your/path/xxx/ && bash check.sh >/dev/null 2>&1

    mysql-schema-sync [-conf] [-dest] [-source] [-sync] [-drop]

    说明:

     mysql-schema-sync -help 
    # mysql-schema-sync -help  
      -conf string
            配置文件名称
      -dest string
            待同步的数据库 eg: test@(10.10.0.1:3306)/test_1
            该项不为空时,忽略读入 -conf参数项
      -drop
            是否对本地多出的字段和索引进行删除 默认否
      -source string
            mysql 同步源,eg test@(127.0.0.1:3306)/test_0
      -sync
            是否将修改同步到数据库中去,默认否
      -tables string
            待检查同步的数据库表,为空则是全部
            eg : product_base,order_*
    

    参考:https://github.com/hidu/mysql-schema-sync 这种只适合于单个数据库的同步,对于不同实例上百个库的同步来说太过复杂;

    上脚本:

    (这脚本适用于不同实例之间表结构同步,user 需要有读写权限)

    #!/usr/bin/env python
    #coding=utf-8
    
    
    import os 
    import json
    import pymysql
    import sys
     
    def get_m_json(filepath,key,value):
        key_ = key.split(".")
        key_length = len(key_)
        with open(filepath, 'r') as f:
            json_data = json.load(f)
            i = 0
            a = json_data
            while i < key_length :
                if i+1 == key_length :
                    a[key_[i]] = "user:pass@("+mysources+":3306)/" + value
                    i = i + 1
                else :
                    a = a[key_[i]]
                    i = i + 1
        f.close()
        return json_data
     
    def get_s_json(filepath,key,value):
        key_ = key.split(".")
        key_length = len(key_)
        with open(filepath, 'r') as f:
            json_data = json.load(f)
            i = 0
            a = json_data
            while i < key_length :
                if i+1 == key_length :
                    a[key_[i]] = "usr:pass@("+mydest+":3306)/" + value
                    i = i + 1
                else :
                    a = a[key_[i]]
                    i = i + 1
        f.close()
        return json_data
     
    def rewrite_json_file(filepath,json_data):
        with open(filepath, 'w') as f:
            json.dump(json_data,f)
        f.close()
     
    if __name__ == '__main__':
        mysources = sys.argv[1]
        mydest = sys.argv[2]
        print ('source:'+mysources)
        print('dest:'+mydest)
        json_path = "/root/go/src/github.com/hidu/mysql-schema-sync/config.json"
    
        mysqlsync="/usr/bin/mysql-schema-sync"
        print("jsonpath:",json_path)
        conn = pymysql.connect(host=mysources, port=3306, user="user", password="pass", database="information_schema")
        cursor = conn.cursor()
        sql = "select SCHEMA_NAME from SCHEMATA where SCHEMA_NAME not in ('mysql','information_schema','performance_schema','test','sys');"
        cursor.execute(sql)
        m_dbs = cursor.fetchall()
        cursor.close()
        conn.close()
        print("sourcedbs:",m_dbs)
        conn = pymysql.connect(host=mydest, port=3306, user="user", password="pass", database="information_schema")
        cursor = conn.cursor()
        sql = "select SCHEMA_NAME from SCHEMATA where SCHEMA_NAME not in ('mysql','information_schema','performance_schema','test','sys');"
        cursor.execute(sql)
        s_dbs = cursor.fetchall()
        cursor.close()
        conn.close()
        print("destdbs:",s_dbs)
        for m_db in m_dbs:
            for s_db in s_dbs:
                if m_db == s_db:
                    m_json_data = get_m_json(json_path,"source",m_db[0])
                    rewrite_json_file(json_path,m_json_data)
                    s_json_data = get_s_json(json_path,"dest",m_db[0])
                    rewrite_json_file(json_path,s_json_data)
                    sync_cmd = str(mysqlsync)+' -conf '+json_path+' -sync 2>/dev/null >> '+mysources.split('.')[0]+'_to_'+mydest.split('.')[0]+'_'+m_db[0]+'.sql'
                    os.system(sync_cmd)
                    sync_cmd1 = str(mysqlsync)+' -conf '+json_path+' -sync 2>/dev/null >>sync.log' 
                    print(sync_cmd1)
                    os.system(sync_cmd1)
                    break 
  • 相关阅读:
    将表中数据生成SQL语句
    遍历页面所有的控件
    MSN不能登陆
    刷新框架页
    JS传参出现乱码
    iframe攻击
    有关于VS调试Javascript的问题
    C#中StringBuilder类的使用
    前瞻XAML
    Asp.Net在SqlServer中的图片存取
  • 原文地址:https://www.cnblogs.com/Camiluo/p/13359532.html
Copyright © 2011-2022 走看看