Dump dumps the database.
(_ context.Context, out io.Writer, _ *storepb.DatabaseSchemaMetadata)
| 87 | |
| 88 | // Dump dumps the database. |
| 89 | func (d *Driver) Dump(_ context.Context, out io.Writer, _ *storepb.DatabaseSchemaMetadata) error { |
| 90 | // mysqldump -u root --databases dbName --no-data --routines --events --triggers --compact |
| 91 | |
| 92 | slog.Debug("begin to dump database", slog.String("database", d.databaseName)) |
| 93 | |
| 94 | db := d.GetDB() |
| 95 | database := d.databaseName |
| 96 | dbType := d.dbType |
| 97 | |
| 98 | // Disable foreign key check. |
| 99 | // mysqldump uses the same mechanism. When there is any schema or data dependency, we have to disable |
| 100 | // the unique and foreign key check so that the restoring will not fail. |
| 101 | // StarRocks has no MySQL UNIQUE_CHECKS/FOREIGN_KEY_CHECKS session variables (and does not |
| 102 | // enforce foreign keys), so emitting the guard makes the dump fail to replay with |
| 103 | // "Unknown system variable 'UNIQUE_CHECKS'". |
| 104 | if d.dbType != storepb.Engine_STARROCKS { |
| 105 | if _, err := io.WriteString(out, disableUniqueAndForeignKeyCheckStmt); err != nil { |
| 106 | return err |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | // Table and view statement. |
| 111 | // We have to dump the table before views because of the structure dependency. |
| 112 | tables, err := getTables(db, database, dbType) |
| 113 | if err != nil { |
| 114 | return errors.Wrapf(err, "failed to get tables of database %q", database) |
| 115 | } |
| 116 | // Construct temporal views and materialized views. |
| 117 | // Create a temporary view with the same name as the view and with columns of |
| 118 | // the same name in order to satisfy views that depend on this view. |
| 119 | // This temporary view will be removed when the actual view is created. |
| 120 | // The properties of each column, are not preserved in this temporary |
| 121 | // view. They are not necessary because other views only need to reference |
| 122 | // the column name, thus we generate SELECT 1 AS colName1, 1 AS colName2. |
| 123 | // This will not be necessary once we can determine dependencies |
| 124 | // between views and can simply dump them in the appropriate order. |
| 125 | // https://sourcegraph.com/github.com/mysql/mysql-server/-/blob/client/mysqldump.cc?L2781 |
| 126 | for _, tbl := range tables { |
| 127 | if tbl.TableType != viewTableType && tbl.TableType != materializedViewType { |
| 128 | continue |
| 129 | } |
| 130 | if tbl.InvalidView != "" { |
| 131 | // We will write the invalid view error string to schema. |
| 132 | stmtFmt := viewStmtFmt |
| 133 | if tbl.TableType == materializedViewType { |
| 134 | stmtFmt = materializedViewStmtFmt |
| 135 | } |
| 136 | if _, err := io.WriteString(out, fmt.Sprintf("%s\n", fmt.Sprintf(stmtFmt, tbl.Name, fmt.Sprintf("-- %s", tbl.InvalidView)))); err != nil { |
| 137 | return err |
| 138 | } |
| 139 | } else { |
| 140 | tempView := getTemporaryView(tbl.Name, tbl.ViewColumns) |
| 141 | if tbl.TableType == materializedViewType { |
| 142 | tempView = getTemporaryMaterializedView(tbl.Name, tbl.ViewColumns) |
| 143 | } |
| 144 | if _, err := io.WriteString(out, fmt.Sprintf("%s\n", tempView)); err != nil { |
| 145 | return err |
| 146 | } |