MigratePrimariesOut migrates all primaries out from the specified node. Internally, for every partition it merely swaps the roles of primary and secondary, so it incurs no data migration. Eventually, the node will have no primaries because they are all turned to secondaries.
(meta Meta, node *util.PegasusNode)
| 86 | // so it incurs no data migration. |
| 87 | // Eventually, the node will have no primaries because they are all turned to secondaries. |
| 88 | func MigratePrimariesOut(meta Meta, node *util.PegasusNode) error { |
| 89 | cmd := fmt.Sprintf("MigratePrimariesOut from=%s", node.CombinedAddr()) |
| 90 | log.Debug(cmd) |
| 91 | |
| 92 | if err := SetMetaLevelSteady(meta); err != nil { |
| 93 | return fmt.Errorf("%s failed: %s", cmd, err) |
| 94 | } |
| 95 | |
| 96 | tables, err := meta.ListAvailableApps() |
| 97 | if err != nil { |
| 98 | return fmt.Errorf("%s failed: %s", cmd, err) |
| 99 | } |
| 100 | |
| 101 | for _, tb := range tables { |
| 102 | tbCmd := cmd + fmt.Sprintf(" table=%s", tb.AppName) |
| 103 | log.Debug(tbCmd) |
| 104 | |
| 105 | partitions, err := ListPrimariesOnNode(meta, node, tb.AppName) |
| 106 | if err != nil { |
| 107 | return fmt.Errorf("%s failed: %s", tbCmd, err) |
| 108 | } |
| 109 | for _, part := range partitions { |
| 110 | from := node |
| 111 | |
| 112 | secIdx := rand.Intn(len(part.Secondaries)) |
| 113 | sec := part.Secondaries[secIdx] |
| 114 | to := replicaNode(sec) |
| 115 | |
| 116 | balanceCmd := tbCmd + fmt.Sprintf(" to=%s gpid=%s", to.CombinedAddr(), part.Pid) |
| 117 | log.Debug(balanceCmd) |
| 118 | |
| 119 | err := meta.Balance(part.Pid, BalanceMovePri, from, to) |
| 120 | if err != nil { |
| 121 | return fmt.Errorf("%s failed: %s", balanceCmd, err) |
| 122 | } |
| 123 | } |
| 124 | } |
| 125 | return nil |
| 126 | } |
| 127 | |
| 128 | // DowngradeNode sets all secondaries from the specified node to inactive state. |
| 129 | // NOTE: this step requires that the node has no primary, otherwise error is returned. |