backup.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. package bo
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "io/fs"
  7. "io/ioutil"
  8. "log"
  9. "os"
  10. "os/exec"
  11. "path/filepath"
  12. "runtime"
  13. "scd_check_tools/conf"
  14. "scd_check_tools/logger"
  15. "scd_check_tools/models/enum"
  16. "scd_check_tools/tools"
  17. "strconv"
  18. "strings"
  19. "time"
  20. "github.com/astaxie/beego/orm"
  21. )
  22. //数据备份还原模型
  23. type Global_backup struct {
  24. Id int `orm:"pk"`
  25. Backtype string
  26. Backdate string
  27. Backstaff string
  28. Backfilepath string
  29. Datastartdate string
  30. Dataenddate string
  31. Backfilesize int64
  32. State int
  33. }
  34. //数据备份还原管理对象
  35. type GlobalBackupMgr struct {
  36. Model Global_backup
  37. DeviceBaseModel
  38. }
  39. func init() {
  40. orm.RegisterModel(new(Global_backup))
  41. }
  42. //将数据还原到指定备份
  43. func (c *GlobalBackupMgr) Recover(backid int) (err error) {
  44. dblog := new(SystemLog)
  45. dblog.SetUserInfo(c.GetUserInfo())
  46. dblog.Audittype = enum.AuditType_admin_dbbackorrecorvey
  47. dblog.Logtype = enum.LogType_Execute
  48. dblog.Eventtype = enum.OptEventType_Bus
  49. dblog.Eventlevel = enum.OptEventLevel_Mid
  50. db := orm.NewOrm()
  51. c.Model.Id = backid
  52. err = db.Read(&c.Model)
  53. if err != nil {
  54. logger.Logger.Error(err)
  55. return err
  56. }
  57. dbcfg, err := c.readDbCnf()
  58. if err != nil {
  59. logger.Logger.Error(err)
  60. return err
  61. }
  62. dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
  63. if dir == "" {
  64. return nil
  65. }
  66. go func() {
  67. if string(runtime.GOOS) == "windows" {
  68. err = c.executiveCommand(dir+string(os.PathSeparator)+`db_restore.bat`, []string{
  69. dbcfg["host"],
  70. dbcfg["port"],
  71. dbcfg["user"],
  72. dbcfg["pwd"],
  73. dbcfg["dbname"],
  74. dir + string(os.PathSeparator) + c.Model.Backfilepath,
  75. },
  76. )
  77. } else {
  78. err = c.executiveCommand(dir+string(os.PathSeparator)+`db_restore.sh`, []string{
  79. dbcfg["host"],
  80. dbcfg["port"],
  81. dbcfg["user"],
  82. dbcfg["pwd"],
  83. dbcfg["dbname"],
  84. dbcfg["dbname"],
  85. dir + string(os.PathSeparator) + c.Model.Backfilepath,
  86. },
  87. )
  88. }
  89. if err != nil {
  90. logger.Logger.Error(err)
  91. return
  92. }
  93. if err != nil {
  94. logger.Logger.Error(err)
  95. dblog.Description = fmt.Sprintf("数据还原失败:%s,操作数据:%+v", err.Error(), c.Model)
  96. dblog.Fail2()
  97. } else {
  98. dblog.Description = fmt.Sprintf("数据还原成功,操作数据:%+v", c.Model)
  99. dblog.Success2()
  100. }
  101. }()
  102. return err
  103. }
  104. //新的备份
  105. func (c *GlobalBackupMgr) Save() (err error) {
  106. dblog := new(SystemLog)
  107. dblog.SetUserInfo(map[string]interface{}{"name": "", "ip": "127.0.0.1"})
  108. dblog.Audittype = enum.AuditType_admin_dbbackorrecorvey
  109. dblog.Logtype = enum.LogType_Insert
  110. dblog.Eventtype = enum.OptEventType_Bus
  111. dblog.Eventlevel = enum.OptEventLevel_Hight
  112. //生成数据库备份
  113. now := time.Now().Format("20060102150405")
  114. bpath := strings.Join([]string{"static", "backup", "db"}, string(os.PathSeparator))
  115. os.MkdirAll(bpath, fs.ModePerm)
  116. c.Model.Backfilepath = bpath + string(os.PathSeparator) + now + ".sql"
  117. c.Model.Backstaff = c.GetUserName()
  118. c.Model.Backdate = tools.NowTime()
  119. c.Model.Backtype = "db"
  120. c.Model.Datastartdate = "1970-01-01 00:00:00"
  121. c.Model.Dataenddate = tools.NowTime()
  122. dbcfg, err := c.readDbCnf()
  123. if err != nil {
  124. logger.Logger.Error(err)
  125. return err
  126. }
  127. dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
  128. if dir == "" {
  129. return nil
  130. }
  131. c.Model.State = 1
  132. db := orm.NewOrm()
  133. newid, err := db.Insert(&c.Model)
  134. if err != nil {
  135. logger.Logger.Error(err)
  136. return nil
  137. }
  138. go func() {
  139. o := orm.NewOrm()
  140. if string(runtime.GOOS) == "windows" {
  141. err = c.executiveCommand(dir+string(os.PathSeparator)+`db_backup.bat`, []string{
  142. dbcfg["host"],
  143. dbcfg["port"],
  144. dbcfg["user"],
  145. dbcfg["pwd"],
  146. dbcfg["dbname"],
  147. dir + string(os.PathSeparator) + c.Model.Backfilepath,
  148. },
  149. )
  150. } else {
  151. err = c.executiveCommand(dir+string(os.PathSeparator)+`db_backup.sh`, []string{
  152. dbcfg["host"],
  153. dbcfg["port"],
  154. dbcfg["user"],
  155. dbcfg["pwd"],
  156. dbcfg["dbname"],
  157. dbcfg["dbname"],
  158. dir + string(os.PathSeparator) + c.Model.Backfilepath,
  159. })
  160. }
  161. if err != nil {
  162. logger.Logger.Error(err)
  163. return
  164. }
  165. f, err := os.Stat(c.Model.Backfilepath)
  166. if err != nil && os.IsNotExist(err) {
  167. logger.Logger.Error(err)
  168. return
  169. }
  170. c.Model.State = 2
  171. c.Model.Id = int(newid)
  172. c.Model.Backfilesize = f.Size()
  173. _, err = o.Update(&c.Model)
  174. if err != nil {
  175. logger.Logger.Error(err)
  176. dblog.Description = fmt.Sprintf("备份数据失败:%s,操作数据:%+v", err.Error(), c.Model)
  177. dblog.Fail2()
  178. } else {
  179. dblog.Description = fmt.Sprintf("备份数据成功,操作数据:%+v", c.Model)
  180. dblog.Success2()
  181. }
  182. }()
  183. return err
  184. }
  185. func (c *GlobalBackupMgr) One() (Global_backup, error) {
  186. o := orm.NewOrm()
  187. err := o.Read(&c.Model)
  188. if err != nil {
  189. log.Println(err)
  190. }
  191. return c.Model, err
  192. }
  193. func (c *GlobalBackupMgr) Delete() (err error) {
  194. dblog := new(SystemLog)
  195. dblog.SetUserInfo(c.GetUserInfo())
  196. dblog.Audittype = enum.AuditType_admin_dbbackorrecorvey
  197. dblog.Logtype = enum.LogType_Delete
  198. dblog.Eventtype = enum.OptEventType_Bus
  199. dblog.Eventlevel = enum.OptEventLevel_Hight
  200. db := orm.NewOrm()
  201. if c.Model.Id == 0 {
  202. return errors.New("无效的ID")
  203. } else {
  204. db.Read(&c.Model)
  205. _, err = db.Delete(&c.Model)
  206. }
  207. if err != nil {
  208. logger.Logger.Error(err)
  209. dblog.Description = fmt.Sprintf("删除数据备份%s失败:%s", c.Model.Backdate, err.Error())
  210. dblog.Fail2()
  211. } else {
  212. ferr := os.Remove("." + string(os.PathSeparator) + c.Model.Backfilepath)
  213. if ferr != nil {
  214. logger.Logger.Error(ferr, c.Model.Backfilepath)
  215. }
  216. dblog.Description = fmt.Sprintf("删除数据备份%s成功", c.Model.Backdate)
  217. dblog.Success2()
  218. }
  219. return err
  220. }
  221. func (c *GlobalBackupMgr) List(param map[string]string, pageno, pagesize int) ([]orm.Params, int, error) {
  222. dblog := new(SystemLog)
  223. dblog.SetUserInfo(c.GetUserInfo())
  224. dblog.Audittype = enum.AuditType_Notice
  225. dblog.Logtype = enum.LogType_Query
  226. dblog.Eventtype = enum.OptEventType_Bus
  227. dblog.Eventlevel = enum.OptEventLevel_Hight
  228. o := orm.NewOrm()
  229. sqlParamters := []interface{}{}
  230. sql := "select t.* from global_backup t where t.backtype='db' "
  231. if v, h := param["backstaff"]; h {
  232. sql += " and t.backstaff like ?"
  233. sqlParamters = append(sqlParamters, "%"+fmt.Sprintf("%s", v)+"%")
  234. }
  235. if v, h := param["backdate"]; h {
  236. ds := strings.Split(tools.IsEmpty(v), ",")
  237. sql += " and t.backdate BETWEEN ? and ?"
  238. sqlParamters = append(sqlParamters, ds[0])
  239. sqlParamters = append(sqlParamters, ds[1])
  240. }
  241. limit := fmt.Sprintf(" order by t.backdate desc limit %d,%d", (pageno-1)*pagesize, pagesize)
  242. r := []orm.Params{}
  243. _, err := o.Raw(sql+limit, sqlParamters).Values(&r)
  244. dblog.Description = fmt.Sprintf("SQL:%s 参数:%+v", sql+limit, sqlParamters)
  245. if err != nil {
  246. logger.Logger.Error(err, dblog.Description)
  247. dblog.Fail2()
  248. return nil, 0, err
  249. }
  250. dblog.Success2()
  251. total := []orm.Params{}
  252. _, err = o.Raw(strings.Replace(sql, "t.*", "count(1) cnt", 1), sqlParamters).Values(&total)
  253. if err != nil {
  254. log.Println(err)
  255. return nil, 0, err
  256. }
  257. totalCnt := 0
  258. if len(total) > 0 {
  259. totalCnt, _ = strconv.Atoi(tools.IsEmpty(total[0]["cnt"]))
  260. }
  261. return r, totalCnt, err
  262. }
  263. func (c *GlobalBackupMgr) readDbCnf() (map[string]string, error) {
  264. rummode := conf.GlobalConfig["runmode"]
  265. fileHanlder, err := os.Open("./conf/mysql-" + rummode + ".cnf")
  266. if err != nil {
  267. return nil, err
  268. }
  269. txt, _ := ioutil.ReadAll(fileHanlder)
  270. fileHanlder.Close()
  271. txtStr := string(txt)
  272. if txtStr == "" {
  273. return nil, errors.New("配置文件格式不正确,请正确配置")
  274. }
  275. cfgdata := map[string]string{}
  276. err = json.Unmarshal(txt, &cfgdata)
  277. if err != nil {
  278. return nil, err
  279. }
  280. return cfgdata, nil
  281. }
  282. func (c *GlobalBackupMgr) executiveCommand(command string, paras []string) error {
  283. //需要执行命令:command
  284. var cmd *exec.Cmd
  285. if string(runtime.GOOS) == "windows" {
  286. cmd = exec.Command(command, paras...)
  287. } else {
  288. cmd = exec.Command("sh", "-c", command)
  289. }
  290. logger.Logger.Debug(fmt.Sprintf("正在进行数据备份,命令:%s 参数:%s", command, paras))
  291. // 获取管道输入
  292. output, err := cmd.StdoutPipe()
  293. if err != nil {
  294. return err
  295. }
  296. if err := cmd.Start(); err != nil {
  297. return err
  298. }
  299. logtxt, err := ioutil.ReadAll(output)
  300. if err != nil {
  301. return err
  302. }
  303. if err := cmd.Wait(); err != nil {
  304. return err
  305. }
  306. logger.Logger.Debug(string(logtxt))
  307. return nil
  308. }