我的编程空间,编程开发者的网络收藏夹
学习永远不晚

【C/C++】ghost ddl脚本简单实现

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

【C/C++】ghost ddl脚本简单实现

目的:本篇是自己用C++实现的ddl的简单脚本(改写自自己的shell,但是还有一部分没完成),用来锻炼自己写C++的能力

头文件exec_ddl.h

```

#include <regex>
#include <cstdlib>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
size_t GetStrCurrTime(std::string &);
#ifndef header_cpp_fun_h
#define header_cpp_fun_h
class CDdlGhost {
private:
//数据库账号,端口,DDL用户,密码,
std::string host;
int port;
std::string user;
std::string password;
std::string database;
std::string tableName;
int threadRunning = 500;
int cthreadRunning = 500;
int maxLagMillis = 3000;
std::string cutOver = "default";
int chunkSize = 1000;
int lockSeconds = 60;
int retries = 3;
static CDdlGhost* instance;
CDdlGhost(std::string host,int port,std::string database,std::string tableName,std::string user,std::string password);

public:
static CDdlGhost* GetSingleInstance(std::string host,int port,std::string database,std::string tableName,std::string user,std::string password);
int GetGhostCmd(std::string sql,std::string &cmd);
int ExecDdlCmd(std::string &cmd);
};
#endif

```

exec_ddl.cpp

```

#include "exec_ddl.h"
//类中静态变量为什么不在类中初始化,是因为静态变量具有外部链接性,文件作用域
CDdlGhost* CDdlGhost::instance = nullptr;

//构造函数
CDdlGhost::CDdlGhost(std::string host,int port,std::string database,std::string tableName,std::string user,std::string password){
    //这里以后正则表达式做安全性过滤
    this->host = host;
    this->port = port;
    this->database = database;
    this->tableName = tableName;
    this->user = user;
    this->password = password;

}
//获取类的单实例函数,这里为什么返回的是指针而不是引用是因为我要用空指针才判断是否单实例
CDdlGhost* CDdlGhost::GetSingleInstance(std::string host,int port,std::string database,std::string tableName,std::string user,std::string password){
    if(nullptr == instance){
        instance = new CDdlGhost(host,port,database,tableName,user,password);
    }

    return instance;

}
//获得表结构更改的命令字符串
int CDdlGhost::GetGhostCmd(std::string sql,std::string &ghostCmd){
    //获取环境变量
    const char* pathEnv = std::getenv("PATH");
    std::string ghostLog;
    //这个变量用来获取当前时间戳
    std::string strTime;
    size_t ret = GetStrCurrTime(strTime);
    if(ret <= 0){
        std::cout<<"获取当前时间戳失败"<<std::endl;
        return 0;
    }
    
    ghostLog=ghostLog+"/data1/upload/ghost_"+tableName+"_"+strTime+".log";
    ghostCmd="gh-ost --ok-to-drop-table --initially-drop-ghost-table --skip-foreign-key-checks --allow-on-master --switch-to-rbr --allow-master-master --exact-rowcount --verbose --initially-drop-old-table ";
    
    ghostCmd=ghostCmd + "--max-load=Threads_running="+std::to_string(threadRunning)+" --critical-load=Threads_running="+std::to_string(cthreadRunning)+" --chunk-size="+std::to_string(chunkSize)+" --cut-over="+cutOver+" --max-lag-millis="+std::to_string(maxLagMillis)+" --cut-over-lock-timeout-seconds="+std::to_string(lockSeconds)+" --default-retries="+std::to_string(retries)+" --host=\'"+host+"' --user='"+user+"' --password='"+password+"' --database='"+database+"'  --table='"+tableName+"' --alter='"+sql+"' --panic-flag-file=/tmp/"+tableName+".ghost.panic.flag --execute  > "+ghostLog+" 2>&1";    

    return 1;
    

}
int CDdlGhost::ExecDdlCmd(std::string &ghostCmd){
    
    pid_t pidGhost;
    int GhostStatus;
    //这里我还要fork一个扫描ghost产生的日志的子进程,但是现在暂时没打开
    //pid_t pidScan;
    
    if((pidGhost = fork()) < 0){
        std::cout<<"pidGhost子进程fork失败"<<std::endl;
        return -2;

    }

    
    //子进程要执行修改表结构命令了
    if(0 == pidGhost){
        //为什么不用system,因为不想子进程fork子进程
        if(execl("/bin/sh","sh","-c",ghostCmd.c_str(),(char *) 0)<0){
            std::cout<<"卧槽,执行命令失败了"<<std::endl;

        }
        _exit(127);

    }
    //另一个子进程,每一秒检查下日志文件,看看是否有锁,有锁就kill,暂时没启用
    

        //等待子进程结束
    if(waitpid(pidGhost,&GhostStatus,0) < 0){
        std::cout<<"等待子进程出现异常"<<std::endl;
        return -1;

    }
        
        

    if(WIFEXITED(GhostStatus)){
        return 0;

    }
    return -3;

}
//获取格式化后的日期字符串
size_t GetStrCurrTime(std::string &strTime){
    time_t now = time(NULL);
    struct tm timeinfo = *localtime(&now);
    char buf[30];
    size_t ret = strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", &timeinfo);
    std::string str(buf);
    strTime = str;
    return ret;}

```

ddl_main.cpp

```

#include <iostream>
#include "exec_ddl.h"
int main(){
    int i=0,ret;
    CDdlGhost *pDdlGhost=CDdlGhost::GetSingleInstance("10.17.4.23",3306,"test","test1","zaixinyuan","test123456");
    if (pDdlGhost == nullptr){
        std::cout<<"分配对象内存失败"<<std::endl;
        return 1;
    }
    std::string ghostCmd;
    i = pDdlGhost->GetGhostCmd("add index cname(c)",ghostCmd);
    ret = pDdlGhost->ExecDdlCmd(ghostCmd);
    std::cout<<"返回结果是:"<<i<<"|"<<ghostCmd<<"|"<<ret<<std::endl;
    if(ret <0){
        std::cout<<"更改表结构失败"<<std::endl;
    }

    delete pDdlGhost;
}

```

编译命令

```

g++ -std=gnu++11 -o ddl_ghost ddl_main.cpp exec_ddl.cpp

```

执行结果:

程序返回结果

【C/C++】ghost ddl脚本简单实现

数据库查看结果

【C/C++】ghost ddl脚本简单实现

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

【C/C++】ghost ddl脚本简单实现

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

【C/C++】ghost ddl脚本简单实现

目的:本篇是自己用C++实现的ddl的简单脚本(改写自自己的shell,但是还有一部分没完成),用来锻炼自己写C++的能力头文件exec_ddl.h```#include #include #include
2023-06-03

C#实现简单计算器功能的脚本怎么写

这篇文章主要介绍了C#实现简单计算器功能的脚本怎么写的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#实现简单计算器功能的脚本怎么写文章都会有所收获,下面我们一起来看看吧。先来张效果图吧(5分钟写好,莫怪)代码
2023-06-29

怎么用C语言脚本实现简易通讯录

这篇文章主要介绍“怎么用C语言脚本实现简易通讯录”,在日常操作中,相信很多人在怎么用C语言脚本实现简易通讯录问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用C语言脚本实现简易通讯录”的疑惑有所帮助!接下来
2023-06-29

Shell脚本实现简单分割字符串

我们有这样一个字符串:info='abcd;efgh'现在想获取abcd和efgh,我们可以简单地用cut工具来获取:fstr=`echo $info | cut -d ; -f 1`sstr=`echo $info | cut -d ;
2022-06-04

C语言如何实现简单的文本编辑器

这篇文章将为大家详细讲解有关C语言如何实现简单的文本编辑器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体内容如下预期实现三个功能,第一,可以对指定的行输入字符串;第二,删除指定行的字符串;第三,显示编
2023-06-15

Linux C线程池简单实现实例

Linux C线程池 三个文件 1 tpool.htypedef struct tpool_work { void (*routine)(void *); void *arg; struct tpool_work
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录