SoFunction
Updated on 2025-03-05

Use go to backup StarRocks table creation statement method example

Golang exports table structure of all databases from StarRocks cluster

useStarRocksThe latest version of the non-stable version is to prevent the cluster from being unable to recover due to unknown bugs, or to regularly backup the metadata information of the production cluster. All require a script or program that can export table structures from the cluster. Choose to use hereGolangCome fromStarRocksExport the table structure of all databases in the cluster.

step

  • Get allDatabase

  • Iterate through eachDatabaseGet all tables

  • Traverse each table to get the table creation statement for each table

  • becauseViewThe output result andTableThe data results are different and classification judgment is required.

  • Write data to a file, and the file can be used directlysourceCommand execution.

Executable detailed code

as follows:

package main
import (
 "database/sql"
 "errors"
 "fmt"
 "log"
 "os"
 _ "/go-sql-driver/mysql"
 "/spf13/pflag"
 "/spf13/viper"
)
type Databases struct {
 Database string
}
type Tables struct {
 Tables string
}
type CreateTable struct {
 Table                string
 CreateString         string
 Character_set_client string
 Collation_connection string
}
const (
 defaultStarRocks  = "127.0.0.1"
 defaultPort       = 9030
 defaultUserName   = "root"
 defaultOutputFile = ""
)
func main() {
 var starRocks, userName, password, outputFile string
 var port int
 var includedSys bool
 (&starRocks, "starrocks", "s", defaultStarRocks, "The address of starrocks without a database name.")
 (&port, "port", "p", defaultPort, "The port of starrocks")
 (&userName, "userName", "u", defaultUserName, "The use name of starrocks")
 (&password, "password", "w", "", "The password of starrocks")
 (&outputFile, "outputFile", "o", defaultOutputFile, "The output file name.")
 (&includedSys, "includedSys", "i", false, "Included the system database or not, default is not.")
 ()
 ("starrocks", ("starrocks"))
 ("port", ("port"))
 ("userName", ("userName"))
 ("password", ("password"))
 ("outputFile", ("outputFile"))
 ("includedSys", ("includedSys"))
 jdbcURL := ("%s:%s@tcp(%s:%d)/", userName, password, starRocks, port)
 sysDB := []string{"_statistics_", "information_schema", "sys"}
 databases := getDatabases(jdbcURL)
 if _, err := (outputFile); err == nil {
  // File exists, remove it
  errRemove := (outputFile)
  if errRemove != nil {
   ("Error removing file:", errRemove)
   return
  }
  ("File removed successfully.")
 }
 for _, db := range databases {
  if !includedSys && containsElement(sysDB, db) {
   continue
  }
  writeToFile(outputFile, ("-- Database: %s\n", db))
  writeToFile(outputFile, ("use %s;\n", db))
  tables := getTables(jdbcURL, db)
  for _, table := range tables {
   if table != "" {
    createTable := getCreateTable(jdbcURL, db, table)
    for k, v := range createTable {
     var objectType string
     if v == "VIEW" {
      objectType = "View"
     } else if v == "TABLE" {
      objectType = "Table"
     }
     writeToFile(outputFile, ("-- %s: %s\n", objectType, table))
     writeToFile(outputFile, ("-- Create %s: \n", objectType))
     writeToFile(outputFile, ("%s\n", k))
    }
   }
  }
 }
}
func writeToFile(outputFile string, s string) {
 file, err := (outputFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
 if err != nil {
  ("Error opening file:", err)
  return
 }
 defer ()
 _, err = ([]byte(s))
 if err != nil {
  ("Error writing to file:", err)
  return
 }
}
func containsElement(list []string, target string) bool {
 for _, element := range list {
  if element == target {
   return true
  }
 }
 return false
}
func getDatabases(jdbcURL string) []string {
 db, err := ("mysql", jdbcURL)
 if err != nil {
  (err)
 }
 defer ()
 res, err := ("show databases")
 if err != nil {
  (err)
 }
 var databases []string
 for () {
  var ds Databases
  err := (&)
  if err != nil {
   (err)
  }
  databases = append(databases, )
 }
 return databases
}
func getTables(jdbcURL, dbName string) []string {
 db, err := ("mysql", jdbcURL+dbName)
 if err != nil {
  (err)
 }
 defer ()
 res, err := ("show tables")
 if err != nil {
  (err)
 }
 var tables []string
 for () {
  var ts Tables
  err := (&)
  if err != nil {
   (err)
  }
  tables = append(tables, )
 }
 return tables
}
func getCreateTable(jdbcURL, dbName, tableName string) map[string]string {
 db, err := ("mysql", jdbcURL+dbName)
 if err != nil {
  (err)
 }
 defer ()
 res, err := ("show create table " + tableName)
 if err != nil {
  (err)
 }
 createTables := make(map[string]string)
 for () {
  var ct CreateTable
  cs, _ := ()
  err := ("")
  if len(cs) == 4 {
   // for view
   err = (&, &, &ct.Character_set_client, &ct.Collation_connection)
   if err != nil {
    (err)
   }
   createTables[] = "VIEW"
  } else if len(cs) == 2 {
   // for table
   err = (&, &)
   if err != nil {
    (err)
   }
   createTables[] = "TABLE"
  }
 }
 return createTables
}

Sample results

After the execution is completed, the result sample:

-- Database: test
use test;
-- Table: test_table
-- Create Table: 
CREATE TABLE `test_table` (
  `day` date NULL COMMENT "sky",
  `id` varchar(65533) NULL COMMENT "id",
  `amount` double NULL COMMENT "value",
  `insert_time` varchar(65533) NULL COMMENT "Data Insert Time"
) ENGINE=OLAP 
UNIQUE KEY(`day`, `id`)
PARTITION BY RANGE(`day`)
(PARTITION p20231020 VALUES [("2023-10-20"), ("2023-10-21")),
PARTITION p20231021 VALUES [("2023-10-21"), ("2023-10-22")),
PARTITION p20231022 VALUES [("2023-10-22"), ("2023-10-23")),
PARTITION p20231023 VALUES [("2023-10-23"), ("2023-10-24")),
PARTITION p20231024 VALUES [("2023-10-24"), ("2023-10-25")),
PARTITION p20231025 VALUES [("2023-10-25"), ("2023-10-26")),
PARTITION p20231027 VALUES [("2023-10-27"), ("2023-10-28")),
PARTITION p20231028 VALUES [("2023-10-28"), ("2023-10-29")),
PARTITION p20231029 VALUES [("2023-10-29"), ("2023-10-30")),
PARTITION p20231030 VALUES [("2023-10-30"), ("2023-10-31")))
DISTRIBUTED BY HASH(`id`)
PROPERTIES (
"replication_num" = "1",
"dynamic_partition.enable" = "false",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.time_zone" = "Asia/Shanghai",
"dynamic_partition.start" = "-7",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "1",
"dynamic_partition.history_partition_num" = "0",
"in_memory" = "false",
"enable_persistent_index" = "false",
"replicated_storage" = "true",
"compression" = "LZ4"
);
-- View: test_view
-- Create View: 
CREATE VIEW `test_view` (`day`, `id`, `amount`, `insert_time`) AS SELECT `test`.`test_table`.`day`, `test`.`test_table`.`id`,`test`.`test_table`.`amount`, `test`.`test_table`.`insert_time`
FROM `test`.`test_table`
WHERE `test`.`test_table`.`day` >= '2023-11-07' ;

Not implemented:

  • Backup MV

  • Backup UDF

  • Back up user role and grant information.

  • Backup Catalog creation statement.

The above code is usedgoVersion is1.21.4, other versions may be a little different. For more information about go backup StarRocks table creation statements, please follow my other related articles!