jenkins流水线搭建数据库自动化构建

jenkins搭建数据库自动化构建

1. jenkins数据库配置

jenkins如何配置数据库配置在网上有很多教程,这里不在赘述

2. pipieline执行流程

本流水线共2个步骤,第一步是执行数据库备份,第二份为执行sql
本流水线sql采用文件上传方式进行读取,所有需要再jenkins页面配置相关参数
因我的数据库使用docker运行,所有直接将data目录进行了全量备份,在自己使用中,可以使用mysqldump等进行备份处理
此构建只涉及测试环境,所有对于权限等比较开放,实际使用请注意权限、备份时数据库压力等
脚本中使用了共享库groovy,对共享库不熟悉者请网上教程参考

3.前端参数搭建

在这里插入图片描述

4.pipeline执行步骤

在这里插入图片描述

5.函数

本次流水线核心为两个函数:execute和backup

execute

execute函数中强制了USE,在实际使用gatDatabaseConnertion时,如果上一次构建是 USE a,那么下一次构建会继承上一次的USE a,默认到a库,为了避免这样的情况,所以通过前端页面指定了数据库实例变量,目的是防止使用人员在使用时,选择表没有加实例前缀名称。
这样也避免不了用户如果通过前缀名依然可以访问其他数据库实例,这要看在在实际使用中的环境,是否加入权限等,因为本环境在配置数据库时没有指定具体的database,所有其他实例依然可以访问
避免此类情况可以在配置时配置具体的database,或者使用限制访问的用户登录数据库

def execute(String statement, String sqlDatabase,List params = [] as List) {
    getDatabaseConnection(type: 'GLOBAL') {
        if("".equals(statement)){
            println ("没有执行的sql")
            sh 'exit 127'
        }
        def arraysSql = statement.split(";")
        println "使用实例:${sqlDatabase}"
        sql(sql: "USE ${sqlDatabase}", parameters: params)
        for(s in arraysSql){
            if (s.trim().size() == 0){
                continue
            }
            if(s.trim().toUpperCase().startsWith("USE")){
                continue
            }
            println ("执行sql:${s}")
            def sql = sql(sql: s, parameters: params)
            Integer index = 0
            // 输出每个元素的值
            sql.each { item ->
                index++
                println "第${index}行数据: ${item}"
            }
            if (index == 0) {
                println "未查询出数据"
            } else {
                println "查询数据总行数:${index}"
            }
        }
    }
}

代码中进行了sql执行并将结果进行了打印

backup

back函数是通过shell脚本实现,通过登录到服务器,进行目录备份,然后删除过期的备份文件,保证磁盘空间的循环利用

def backup(configName, source, String tagerfilename = "mysqlbackup-${BUILD_NUMBER}" as String, String backdir="/data/backup", Integer retentionTime = 0){
    def backupsh = libraryResource'directory-backup.sh'
    writeFile(file:'directory-backup.sh',text:backupsh)
    sshPublisher(publishers: [sshPublisherDesc(configName: "${configName}", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand:
            "cd /data" +
                    "&& chmod a+x directory-backup.sh" +
                    "&& ./directory-backup.sh ${source} ${backdir} ${tagerfilename} ${retentionTime}"
            , execTimeout: 1200000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', 
            remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'directory-backup.sh')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}

directory-backup.sh

#!/bin/bash
#$1 备份文件或目录
#$2 存放文件的目录
#$3 备份文件的名称
#$4 删除过期文件/天
echo start backup $(date "+%Y-%m-%d %H:%M:%S")
#需要备份的文件或目录
source=$1
#存在文件的目录
backup_dir=$2/$(date "+%Y%m%d")
#备份文件的名称
filename="${backup_dir}/$3"_$(date "+%Y-%m-%d_%H-%M-%S").tar.gz
echo this is filename $filename
echo this is Storage directory $backup_dir
#判断目录是否存在,不存在创建
if [ ! -d $backup_dir ];
then
    mkdir -p $backup_dir;
fi
#开始备份文件
tar -czvf "${filename}" "${source}"
#删除过期文件
echo "开始删除过期文件"
for file in $(ls $2)
do
file="$2/$file"
 if [ -d "$file" ] ; then
#    获取文件夹的日期
   delete=${file##*/}
#判断文件夹日期小于等于保留的日期,如果是则删除
   if [[ "$delete" =~ ^20[0-9]{6}$ ]] && [ "$delete" -le $(date "+%Y%m%d" -d "$4 day ago") ]; then
     echo "rm -rf $file"
     rm -rf $file""
   fi
 fi
done
echo "过期文件删除执行结束"

echo stop backup $(date "+%Y-%m-%d %H:%M:%S")