restoreBasic.py 6.5 KB
Newer Older
A
Alex Duan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
###################################################################
#           Copyright (c) 2016 by TAOS Technologies, Inc.
#                     All rights reserved.
#
#  This file is proprietary and confidential to TAOS Technologies.
#  No part of this file may be reproduced, stored, transmitted,
#  disclosed or used in any form or by any means other than as
#  expressly provided by the written permission from Jianhui Tao
#
###################################################################

# -*- coding: utf-8 -*-


from util.log import *
from util.cases import *
from util.sql import *
from util.common import *
from util.sqlset import *
from util.dnodes import *
21 22
from util.autogen import *
from util.cluster import *
A
Alex Duan 已提交
23 24 25 26

import random
import os
import subprocess
27 28
import shutil
import time
A
Alex Duan 已提交
29 30
    

A
Alex Duan 已提交
31
class RestoreBasic:
A
Alex Duan 已提交
32 33 34 35
    # init
    def init(self, conn, logSql, replicaVar=1):
        self.replicaVar = int(replicaVar)
        tdSql.init(conn.cursor())
36
        self.dnodes_num = 5
A
Alex Duan 已提交
37

38 39 40 41
        # get from global
        # test
        self.dnodes = cluster.dnodes
        num = len(self.dnodes)
A
Alex Duan 已提交
42

A
Alex Duan 已提交
43 44
        if num < self.dnodes_num :
            tdLog.exit(f" cluster dnode is less than {self.dnodes_num}. num={num}")
A
Alex Duan 已提交
45

A
Alex Duan 已提交
46 47 48 49 50 51
        # create data
        self.dbname = "db"
        self.stable = "st"
        self.child_count = 100
        self.insert_rows = 10000
        self.create_data()
52 53 54 55 56 57 58 59 60

    #  create data
    def create_data(self):
        gen = AutoGen()
        gen.create_db(self.dbname, 8, 3)
        gen.create_stable(self.stable, 5, 10, 8, 8)
        gen.create_child(self.stable, "d", self.child_count)
        gen.set_batch_size(1000)
        gen.insert_data(self.insert_rows)
A
Alex Duan 已提交
61 62 63 64
        
        tdSql.execute(f"flush database {self.dbname}")
        # put some duplicate ts on wal
        gen.insert_data(self.insert_rows%100)
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97

        for i in range(self.dnodes_num):
            sql = f"create qnode on dnode {i+1}"
            tdSql.execute(sql)


    # status
    def check_status_corrent(self):
        # query
        tdSql.query(f" show {self.dbname}.vgroups")

        # check 8 vgroups
        tdSql.checkRows(8)

        # check data corrent
        for i in range(8):
            leader = False
            for j in range(3):
                status = tdSql.getData(i, 4 + j*2)
                if status == "leader":
                    leader = True
                elif status == "follower":
                    pass
                else:
                    tdLog.info(f" check vgroups status not leader or follower. i={i} j={j} status={status}")
                    return False
            
            # check leader
            if  leader == False:
                tdLog.info(f" check vgroups not found leader i={i} ")
                return False

        # info
A
Alex Duan 已提交
98
        tdLog.info("check vgroups status successfully.")
99 100 101 102 103 104
        return True

    # check data corrent
    def check_corrent(self):
        # check status
        status = False
A
Alex Duan 已提交
105
        for i in range(100): 
106 107 108 109
            if self.check_status_corrent():
                 status = True
                 break
            else:
A
Alex Duan 已提交
110 111
                time.sleep(0.5)
                tdLog.info(f"sleep 500ms retry {i} to check status again...") 
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

        if status == False:
            tdLog.exit("check vgroups status failed, exit.")             
            
        # check rows count
        sql = f"select count(ts) from {self.dbname}.{self.stable}"
        tdSql.query(sql)
        tdSql.checkData(0, 0, self.child_count* self.insert_rows)


    # restore dnode
    def restore_dnode(self, index):
        tdLog.info(f"start restore dnode {index}")
        dnode = self.dnodes[index - 1]
        
        # stop dnode
        tdLog.info(f"stop dnode {index}")
        dnode.stoptaosd()

        # remove dnode folder
        try:
            shutil.rmtree(dnode.dataDir)
A
Alex Duan 已提交
134
            tdLog.info(f"delete dir {dnode.dataDir} successful")
135
        except OSError as x:
A
Alex Duan 已提交
136
            tdLog.exit(f"remove path {dnode.dataDir} error : {x.strerror}")
137 138 139 140 141

        dnode.starttaosd()
        
        # exec restore
        sql = f"restore dnode {index}"
A
Alex Duan 已提交
142
        tdLog.info(sql)
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
        tdSql.execute(sql)
        self.check_corrent()

    # restore vnode
    def restore_vnode(self, index):
        tdLog.info(f"start restore vnode on dnode {index}")
        dnode = self.dnodes[index - 1]
        del_dir = f"{dnode.dataDir}/vnode"

        # stop dnode
        tdLog.info(f"stop dnode {index}")
        dnode.stoptaosd()
        
        # remove dnode folder
        try:
            shutil.rmtree(del_dir)
A
Alex Duan 已提交
159
            tdLog.info(f"delete dir {del_dir} successful")
160
        except OSError as x:
A
Alex Duan 已提交
161
            tdLog.exit(f"remove path {del_dir} error : {x.strerror}")
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185

        dnode.starttaosd()
        
        # exec restore
        sql = f"restore vnode on dnode {index}"
        tdSql.execute(sql)

        # check result
        self.check_corrent()

        
    # restore mnode
    def restore_mnode(self, index):
        tdLog.info(f"start restore mnode {index}")
        dnode = self.dnodes[index - 1]
        del_dir = f"{dnode.dataDir}/mnode"
        
        # stop dnode
        tdLog.info(f"stop dnode {index}")
        dnode.stoptaosd()

        # remove dnode folder
        try:
            shutil.rmtree(del_dir)
A
Alex Duan 已提交
186
            tdLog.info(f"delete dir {del_dir} successful")
187
        except OSError as x:
A
Alex Duan 已提交
188
            tdLog.exit(f"remove path {del_dir} error : {x.strerror}")
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210

        dnode.starttaosd()
        
        # exec restore
        sql = f"restore mnode on dnode {index}"
        tdSql.execute(sql)
        self.check_corrent()


    # restore qnode
    def restore_qnode(self, index):
        tdLog.info(f"start restore qnode on dnode {index}")
        dnode = self.dnodes[index - 1]
        del_dir = f"{dnode.dataDir}/qnode"

        # stop dnode
        tdLog.info(f"stop dnode {index}")
        dnode.stoptaosd()

        # remove dnode folder
        try:
            shutil.rmtree(del_dir)
A
Alex Duan 已提交
211
            tdLog.info(f"delete dir {del_dir} successful")
212
        except OSError as x:
A
Alex Duan 已提交
213
            tdLog.exit(f"remove path {del_dir} error : {x.strerror}")
214 215 216 217 218 219 220 221 222 223 224 225

        # start dnode 
        dnode.starttaosd()
        
        # exec restore
        sql = f"restore qnode on dnode {index}"
        tdSql.execute(sql)
        self.check_corrent()

        # path exist
        qfile = f"{del_dir}/qnode.json"
        if os.path.exists(qfile) == False:
A
Alex Duan 已提交
226 227 228
            tdLog.exit(f"qnode restore failed. qnode.json is not exist. {qfile}")
        else:
            tdLog.info(f"check qnode.json restore ok. {qfile}")
229
    
A
Alex Duan 已提交
230 231 232 233
    # stop
    def stop(self):
        tdSql.close()

A
Alex Duan 已提交
234