From bcb3c6463dd34e8f828ed8b5d927eb94482a0115 Mon Sep 17 00:00:00 2001 From: Roberto Rodriguez Alcala Date: Tue, 20 Feb 2018 10:45:52 -0800 Subject: [PATCH] Abort rocksdb startup if O_DIRECT is requested but not supported (#793) (#793) Summary: This change adds a check to see whether the filesystem backing rocksdb_datadir allows O_DIRECT when use_direct_reads is true and prevents rocksdb from coming up. This fixes https://github.com/facebook/mysql-5.6/issues/778 Closes https://github.com/facebook/mysql-5.6/pull/793 Differential Revision: D6995213 (https://github.com/facebook/mysql-5.6/commit/a62014fdc867dbd702543c0cc5e96c48643f0a15) Pulled By: rralcala fbshipit-source-id: c61900b39ab --- .../suite/rocksdb/r/use_direct_reads.result | 18 +++++++++ .../suite/rocksdb/t/use_direct_reads.test | 37 +++++++++++++++++++ storage/rocksdb/ha_rocksdb.cc | 29 +++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 mysql-test/suite/rocksdb/r/use_direct_reads.result create mode 100644 mysql-test/suite/rocksdb/t/use_direct_reads.test diff --git a/mysql-test/suite/rocksdb/r/use_direct_reads.result b/mysql-test/suite/rocksdb/r/use_direct_reads.result new file mode 100644 index 000000000000..45a21c3c6299 --- /dev/null +++ b/mysql-test/suite/rocksdb/r/use_direct_reads.result @@ -0,0 +1,18 @@ +Checking direct reads +CREATE TABLE t1 (pk INT PRIMARY KEY DEFAULT '0', a INT(11), b CHAR(8)) ENGINE=rocksdb; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL DEFAULT '0', + `a` int(11) DEFAULT NULL, + `b` char(8) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=ROCKSDB DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES (1, 1,'a'); +INSERT INTO t1 (a,b) VALUES (2,'b'); +set global rocksdb_force_flush_memtable_now=1; +SELECT a,b FROM t1; +a b +1 a +2 b +DROP TABLE t1; diff --git a/mysql-test/suite/rocksdb/t/use_direct_reads.test b/mysql-test/suite/rocksdb/t/use_direct_reads.test new file mode 100644 index 000000000000..c347a85518f4 --- /dev/null +++ b/mysql-test/suite/rocksdb/t/use_direct_reads.test @@ -0,0 +1,37 @@ +--source include/have_rocksdb.inc + +--perl +use Cwd 'abs_path'; + +open(FILE, ">", "$ENV{MYSQL_TMP_DIR}/data_in_shm.inc") or die; +my $real_path= abs_path($ENV{'MYSQLTEST_VARDIR'}); +my $in_shm= index($real_path, "/dev/shm") != -1; +print FILE "let \$DATA_IN_SHM= $in_shm;\n"; +close FILE; +EOF + +--source $MYSQL_TMP_DIR/data_in_shm.inc +--remove_file $MYSQL_TMP_DIR/data_in_shm.inc + +if ($DATA_IN_SHM) +{ + --skip DATADIR is in /dev/shm, possibly due to --mem +} + +--echo Checking direct reads +--let $_mysqld_option=--rocksdb_use_direct_reads=1 +--source include/restart_mysqld_with_option.inc + +CREATE TABLE t1 (pk INT PRIMARY KEY DEFAULT '0', a INT(11), b CHAR(8)) ENGINE=rocksdb; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES (1, 1,'a'); +INSERT INTO t1 (a,b) VALUES (2,'b'); +set global rocksdb_force_flush_memtable_now=1; +--sorted_result +SELECT a,b FROM t1; +DROP TABLE t1; + +# cleanup +--let _$mysqld_option= +--source include/restart_mysqld.inc + diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 2995cf3f3019..38fc177f275e 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -4179,6 +4179,35 @@ static int rocksdb_init_func(void *const p) { DBUG_RETURN(HA_EXIT_FAILURE); } + // Check whether the filesystem backing rocksdb_datadir allows O_DIRECT + if (rocksdb_db_options->use_direct_reads) { + rocksdb::EnvOptions soptions; + rocksdb::Status check_status; + rocksdb::Env *const env = rocksdb_db_options->env; + + std::string fname = format_string("%s/DIRECT_CHECK", rocksdb_datadir); + if (env->FileExists(fname).ok()) { + std::unique_ptr file; + soptions.use_direct_reads = true; + check_status = env->NewSequentialFile(fname, &file, soptions); + } else { + std::unique_ptr file; + soptions.use_direct_writes = true; + check_status = env->ReopenWritableFile(fname, &file, soptions); + if (file != nullptr) { + file->Close(); + } + env->DeleteFile(fname); + } + + if (!check_status.ok()) { + sql_print_error("RocksDB: Unable to use direct io in rocksdb-datadir:" + "(%s)", check_status.getState()); + rdb_open_tables.free_hash(); + DBUG_RETURN(HA_EXIT_FAILURE); + } + } + if (rocksdb_db_options->allow_mmap_writes && rocksdb_db_options->use_direct_io_for_flush_and_compaction) { // See above comment for allow_mmap_reads. (NO_LINT_DEBUG)