diff options
Diffstat (limited to 'mysql.py')
| -rw-r--r-- | mysql.py | 229 |
1 files changed, 99 insertions, 130 deletions
@@ -11,48 +11,51 @@ from time import sleep from benchmark import Benchmark from common_targets import common_targets -import chattyparser cwd = os.getcwd() prepare_cmd = ("sysbench oltp_read_only --db-driver=mysql --mysql-user=root " "--mysql-socket="+cwd+"/mysql_test/socket --tables=5 --table-size=1000000 prepare").split() -cmd = ("sysbench oltp_read_only --threads={} --time=60 --tables=5 " - "--db-driver=mysql --mysql-user=root --mysql-socket={}/mysql_test/socket run") +cmd = ("sysbench oltp_read_only --threads={nthreads} --time=1 --tables=5 " + "--db-driver=mysql --mysql-user=root --mysql-socket="+cwd+"/mysql_test/socket run") -server_cmd = ("mysqld -h {0}/mysql_test --socket={0}/mysql_test/socket " - "--secure-file-priv=").format(cwd).split() +server_cmd = (shutil.which("mysqld")+" -h "+cwd+"/mysql_test --socket="+cwd+"/mysql_test/socket " + "--secure-file-priv= ").format(cwd).split() class Benchmark_MYSQL( Benchmark ): def __init__(self): self.name = "mysql" self.descrition = """See sysbench documentation.""" + + # mysqld fails with hoard somehow self.targets = copy.copy(common_targets) del(self.targets["hoard"]) - if "klmalloc" in self.targets: - del(self.targets["klmalloc"]) - self.nthreads = range(1, multiprocessing.cpu_count() * 4 + 1, 2) - - self.results = {"args": {"nthreads" : self.nthreads}, - "targets" : self.targets} - self.results.update({t : {} for t in self.targets}) - - def start_and_wait_for_server(self, verbose, log=None): - if not log: - log = os.devnull - - with open(log, "wb") as f: - self.server = subprocess.Popen(server_cmd, env=os.environ, - stdout=f, - stderr=f, - universal_newlines=True) - #TODO make sure server comes up !!!! + + self.args = {"nthreads" : range(1, multiprocessing.cpu_count() * 4 + 1, 2)} + self.cmd = cmd + self.perf_cmd = "" + + self.requirements = ["mysqld", "sysbench"] + super().__init__() + + def start_and_wait_for_server(self, verbose, cmd_prefix=""): + actual_cmd = cmd_prefix.split() + server_cmd + if verbose: + print("Starting server with:", actual_cmd) + + self.server = subprocess.Popen(actual_cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + #TODO make sure server comes up ! sleep(5) return self.server.poll() == None def prepare(self, verbose=False): + if not super().prepare(verbose=verbose): + return False # Setup Test Environment if not os.path.exists("mysql_test"): print("Prepare mysqld directory and database") @@ -62,11 +65,11 @@ class Benchmark_MYSQL( Benchmark ): if b"MariaDB" in subprocess.run(["mysqld", "--version"], stdout=PIPE).stdout: init_db_cmd = ["mysql_install_db", "--basedir=/usr", - "--datadir={}/mysql_test".format(cwd)] + "--datadir="+cwd+"/mysql_test"] if verbose: print("MariaDB detected") else: - init_db_cmd = ["mysqld", "-h", "{}/mysql_test".format(cwd), + init_db_cmd = ["mysqld", "-h", cwd+"/mysql_test", "--initialize-insecure"] if verbose: print("Oracle MySQL detected") @@ -77,7 +80,7 @@ class Benchmark_MYSQL( Benchmark ): print(p.stderr) return False - if not self.start_and_wait_for_server(verbose, "mysqld.log"): + if not self.start_and_wait_for_server(verbose): print("Starting mysqld failed") return False @@ -110,120 +113,88 @@ class Benchmark_MYSQL( Benchmark ): print("Delete mysqld directory") shutil.rmtree("mysql_test") - def run(self, verbose=False, runs=3): - for run in range(1, runs + 1): - print(str(run) + ". run") - - # run cmd for each target - n = len(self.nthreads) - for tname, t in self.targets.items(): - os.environ["LD_PRELOAD"] = "build/print_status_on_exit.so " + t["LD_PRELOAD"] - - if not self.start_and_wait_for_server(verbose, "mysqld.log"): - print("Can't start server for", tname + ".") - print("Aborting Benchmark.") - return False - - for i, thread in enumerate(self.nthreads): - print(tname + ":", i + 1, "of", n, "\r", end='') - - target_cmd = cmd.format(thread, cwd).split(" ") - p = subprocess.run(target_cmd, stderr=PIPE, stdout=PIPE, - universal_newlines=True) - - if p.returncode != 0: - print("\n" + " ".join(target_cmd), "exited with", p.returncode, ".\n Aborting Benchmark.") - print(tname, t) - print(p.stderr) - print(p.stdout) - self.server.kill() - self.server.wait() - return False - - result = {} - - result["transactions"] = re.search("transactions:\s*(\d*)", p.stdout).group(1) - result["queries"] = re.search("queries:\s*(\d*)", p.stdout).group(1) - # Latency - result["min"] = re.search("min:\s*(\d*.\d*)", p.stdout).group(1) - result["avg"] = re.search("avg:\s*(\d*.\d*)", p.stdout).group(1) - result["max"] = re.search("max:\s*(\d*.\d*)", p.stdout).group(1) - - with open("/proc/"+str(self.server.pid)+"/status", "r") as f: - for l in f.readlines(): - if l.startswith("VmHWM:"): - result["rssmax"] = l.replace("VmHWM:", "").strip().split()[0] - break - - if not thread in self.results: - self.results[tname][thread] = [result] - else: - self.results[tname][thread].append(result) + def pretarget_hook(self, target, run, verbose): + if not self.start_and_wait_for_server(verbose, + cmd_prefix=target[1]["cmd_prefix"]): + print("Can't start server for", target[0] + ".") + print("Aborting Benchmark.") + print(target[1]["cmd_prefix"]) + print(self.server.stderr.read()) + return False - print() + def posttarget_hook(self, target, run, verbose): + self.server.kill() + self.server.wait() - self.server.kill() - self.server.wait() + def process_stdout(self, result, stdout): + result["transactions"] = re.search("transactions:\s*(\d*)", stdout).group(1) + result["queries"] = re.search("queries:\s*(\d*)", stdout).group(1) + # Latency + result["min"] = re.search("min:\s*(\d*.\d*)", stdout).group(1) + result["avg"] = re.search("avg:\s*(\d*.\d*)", stdout).group(1) + result["max"] = re.search("max:\s*(\d*.\d*)", stdout).group(1) - return True + with open("/proc/"+str(self.server.pid)+"/status", "r") as f: + for l in f.readlines(): + if l.startswith("VmHWM:"): + result["rssmax"] = l.replace("VmHWM:", "").strip().split()[0] + break def analyse(self, verbose=False): + nthreads = [0] + list(self.args["nthreads"]) + failed = False + self.results["hist"] = {} os.environ["LD_PRELOAD"] = "build/chattymalloc.so" - os.environ["CHATTYMALLOC_OPTS"] = "store=false" - if not self.start_and_wait_for_server(verbose, "mysqld.log"): - print("Can't start server.") - print("Aborting analysing.") - return False - - self.server.kill() - self.server.wait() - self.results["hist"][0] = chattyparser.hist() - - runs = len(self.nthreads) - for i, t in enumerate(self.nthreads): + runs = len(nthreads) + for i, t in enumerate(nthreads): print("analysing", i + 1, "of", runs, "\r", end='') - os.environ["LD_PRELOAD"] = "build/chattymalloc.so" - os.environ["CHATTYMALLOC_OPTS"] = "store=false" - if not self.start_and_wait_for_server(verbose, "mysqld.log"): + if not self.start_and_wait_for_server(verbose): print("Can't start server.") print("Aborting analysing.") return False - os.environ["LD_PRELOAD"] = "" - - target_cmd = cmd.format(t, cwd).split(" ") - p = subprocess.run(target_cmd, stderr=PIPE, stdout=PIPE, - universal_newlines=True) + if t != 0: + target_cmd = self.cmd.format(nthreads=t).split(" ") + p = subprocess.run(target_cmd, + stderr=PIPE, + stdout=PIPE, + universal_newlines=True) - if p.returncode != 0: - print("\n" + " ".join(target_cmd), "exited with", p.returncode, ".\n Aborting analysing.") - print(p.stderr) - print(p.stdout) - return False + if p.returncode != 0: + print("\n" + " ".join(target_cmd), "exited with", p.returncode, ".\n Aborting analysing.") + print(p.stderr) + print(p.stdout) + failed = True self.server.kill() self.server.wait() - self.results["hist"][t] = chattyparser.hist(path="chattymalloc.data") + + self.results["hist"][t] = self.parse_chattymalloc_data() + + if failed: + print(self.server.stdout.read()) + print(self.server.stderr.read()) + return False print() def summary(self, sd=None): - # linear plot - nthreads = self.results["args"]["nthreads"] - targets = self.results["targets"] - y_mapping = {v: i for i, v in enumerate(nthreads)} - sd = sd or "" + targets = self.results["targets"] + nthreads = list(self.results["args"]["nthreads"]) + # linear plot for target in targets: - y_vals = [0] * len(nthreads) - for thread, measures in self.results[target].items(): - d = [int(m["transactions"]) for m in measures] - y_vals[y_mapping[thread]] = np.mean(d) - plt.plot(nthreads, y_vals, label=target, linestyle='-', marker='.', color=targets[target]["color"]) + y_vals = [] + print(self.results[target]) + for perm in self.iterate_args(): + d = [int(m["transactions"]) for m in self.results[target][perm]] + y_vals.append(np.mean(d)) + plt.plot(nthreads, y_vals, label=target, linestyle='-', + marker='.', color=targets[target]["color"]) plt.legend() plt.xlabel("threads") @@ -233,17 +204,14 @@ class Benchmark_MYSQL( Benchmark ): plt.clf() # bar plot - nthreads = list(self.results["args"]["nthreads"]) - targets = self.results["targets"] - y_mapping = {v: i for i, v in enumerate(nthreads)} - for i, target in enumerate(targets): + y_vals = [] + for perm in self.iterate_args(): + d = [int(m["transactions"]) for m in self.results[target][perm]] + y_vals.append(np.mean(d)) x_vals = [x-i/8 for x in range(1, len(nthreads) + 1)] - y_vals = [0] * len(nthreads) - for thread, measures in self.results[target].items(): - d = [int(m["transactions"]) for m in measures] - y_vals[y_mapping[thread]] = np.mean(d) - plt.bar(x_vals, y_vals, width=0.2, label=target, align="center", color=targets[target]["color"]) + plt.bar(x_vals, y_vals, width=0.2, label=target, align="center", + color=targets[target]["color"]) plt.legend() plt.xlabel("threads") @@ -276,14 +244,15 @@ class Benchmark_MYSQL( Benchmark ): plt.savefig(os.path.join(sd, self.name + ".hist." + str(t) + ".png")) plt.clf() + # Memusage - y_mapping = {v : i for i, v in enumerate(nthreads)} for target in targets: - y_vals = [0] * len(nthreads) - for thread, measures in self.results[target].items(): - d = [int(m["rssmax"]) for m in measures] - y_vals[y_mapping[thread]] = np.mean(d) - plt.plot(nthreads, y_vals, marker='.', linestyle='-', label=target, color=targets[target]["color"]) + y_vals = [] + for perm in self.iterate_args(): + d = [int(m["rssmax"]) for m in self.results[target][perm]] + y_vals.append(np.mean(d)) + plt.plot(nthreads, y_vals, marker='.', linestyle='-', label=target, + color=targets[target]["color"]) plt.legend() plt.xlabel("threads") |
