Skip to content

Commit

Permalink
Fix fd out of range error for WSfile
Browse files Browse the repository at this point in the history
Summary:
When mysys try to find filename from its fd, for WSFiles, its data isn't stored in FileInfoVector, thus in my_filename(), it will return  "<fd out of range>", which is very confusing.


The change is to fetch WSFile name during my_filename() by checking fd

Test Plan:
CI

Before:

RuntimeError: CopyReason.OLM copy failed with exit status 2 Error: mysqldump: Got error: 3: Error writing file '<fd out of range>' (OS errno 5 - Input/output error) when executing 'SELECT INTO OUTFILE'

After:
RuntimeError: CopyReason.OLM copy failed with exit status 2 Error: mysqldump: Got error: 3: Error writing file 'ws://olm/0/1709957685.8442662/mysql.replicaset.b2852/data.db8317960b/xid_map.txt' (OS errno 5 - Input/output error) when executing 'SELECT INTO OUTFILE'


mytest sql_wsenv.select_into_outfile_error_wsenv --sql-wsenv

```
worker[1] [SQL WSEnv] Setting mysqld config:
worker[1]   sql_wsenv_tenant=myrocks_automation
worker[1]   sql_wsenv_oncall=mysql_eng_poc
worker[1]   sql_wsenv_uri_prefix=ws://
worker[1]   sql_wsenv_lib_name=librocks_object_factory.so
worker[1]   sql_wsenv_mtr_path=ws://ws.flash.ldc1validation1/mysql/1712210262/devvm12268.ftw0.facebook.com/8.0-Debug/sql_wsenv.select_into_outfile_error_wsenv-innodb
worker[1] [SQL WSEnv] mkdir 'ws://ws.flash.ldc1validation1/mysql/1712210262/devvm12268.ftw0.facebook.com/8.0-Debug/sql_wsenv.select_into_outfile_error_wsenv-innodb'
worker[1] [SQL WSEnv] mysqld.1:
worker[1]   sql_wsenv_tenant=myrocks_automation
worker[1]   sql_wsenv_oncall=mysql_eng_poc
worker[1]   sql_wsenv_uri_prefix=ws://
worker[1]   sql_wsenv_lib_name=librocks_object_factory.so
[ 33%] sql_wsenv.select_into_outfile_error_wsenv 'innodb'  [ pass ]   9844
worker[1] [SQL WSEnv] Removing 'ws://ws.flash.ldc1validation1/mysql/1712210262/devvm12268.ftw0.facebook.com/8.0-Debug/sql_wsenv.select_into_outfile_error_wsenv-rocksdb'
wscli rmr blocked for this path! Contact WS for more information
xargs: wscli: exited with status 255; aborting
worker[1] [SQL WSEnv] Setting mysqld config:
worker[1]   sql_wsenv_tenant=myrocks_automation
worker[1]   sql_wsenv_oncall=mysql_eng_poc
worker[1]   sql_wsenv_uri_prefix=ws://
worker[1]   sql_wsenv_lib_name=librocks_object_factory.so
worker[1]   sql_wsenv_mtr_path=ws://ws.flash.ldc1validation1/mysql/1712210262/devvm12268.ftw0.facebook.com/8.0-Debug/sql_wsenv.select_into_outfile_error_wsenv-rocksdb
worker[1] [SQL WSEnv] mkdir 'ws://ws.flash.ldc1validation1/mysql/1712210262/devvm12268.ftw0.facebook.com/8.0-Debug/sql_wsenv.select_into_outfile_error_wsenv-rocksdb'
worker[1] [SQL WSEnv] mysqld.1:
worker[1]   sql_wsenv_tenant=myrocks_automation
worker[1]   sql_wsenv_oncall=mysql_eng_poc
worker[1]   sql_wsenv_uri_prefix=ws://
worker[1]   sql_wsenv_lib_name=librocks_object_factory.so
[ 66%] sql_wsenv.select_into_outfile_error_wsenv 'rocksdb'  [ pass ]  10635
[100%] shutdown_report                           [ pass ]
------------------------------------------------------------------------------
```

Reviewers: saumitr, #mysql_eng

Reviewed By: saumitr

Subscribers: saumitr

Differential Revision: https://phabricator.intern.facebook.com/D54728856
  • Loading branch information
Luqun Lou authored and luqun committed Apr 20, 2024
1 parent a47ffdc commit 992265e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
call mtr.add_suppression("Error writing file .*");
create table t1 (pk int primary key,col1 varchar(10));
insert into t1 values (1,"aaa"),(2,"bbb"),(3,"ccc"),(4,"ddd"),(5,"eee");
set enable_sql_wsenv=1;
SET @debug_save= @@GLOBAL.DEBUG;
SET @@DEBUG= 'd,simulate_file_write_error';
SELECT * FROM t1 INTO OUTFILE 'OUTPUT_FILE';
ERROR HY000: Can't create/write to file 'OUTPUT_FILE' (OS errno 5 - Input/output error)
SET @@DEBUG=@debug_save;
set enable_sql_wsenv=0;
drop table t1;
# restart
21 changes: 21 additions & 0 deletions mysql-test/suite/sql_wsenv/t/select_into_outfile_error_wsenv.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# scenario1: basic
call mtr.add_suppression("Error writing file .*");
create table t1 (pk int primary key,col1 varchar(10));
insert into t1 values (1,"aaa"),(2,"bbb"),(3,"ccc"),(4,"ddd"),(5,"eee");
set enable_sql_wsenv=1;

SET @debug_save= @@GLOBAL.DEBUG;
SET @@DEBUG= 'd,simulate_file_write_error';

# dump data into file
--let $output_file=$SQL_WSENV_MTR_PATH/s1_t1.txt
--replace_result $output_file OUTPUT_FILE
--ERROR 1
--eval SELECT * FROM t1 INTO OUTFILE '$output_file'

SET @@DEBUG=@debug_save;
set enable_sql_wsenv=0;
drop table t1;

# restart mysqld
--source include/restart_mysqld.inc
10 changes: 10 additions & 0 deletions mysys/my_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "mysql/psi/mysql_mutex.h"
#include "mysql/service_mysql_alloc.h"
#include "mysys/my_static.h"
#include "mysys/my_wsfile.h"
#include "mysys/mysys_priv.h"
#include "sql/malloc_allocator.h"
#include "sql/stateless_allocator.h"
Expand Down Expand Up @@ -190,6 +191,9 @@ namespace file_info {
*/
void RegisterFilename(File fd, const char *file_name, OpenType type_of_file) {
if (fivp == nullptr) return;
// WS files aren't registered
if (fd >= WS_START_FD) return;

assert(fd > -1);
FileInfoVector &fiv = *fivp;
MUTEX_LOCK(g, &THR_LOCK_open);
Expand Down Expand Up @@ -217,6 +221,8 @@ void UnregisterFilename(File fd) {
FileInfoVector &fiv = *fivp;
MUTEX_LOCK(g, &THR_LOCK_open);

// WS files aren't registered
if (fd >= WS_START_FD) return;
if (static_cast<size_t>(fd) >= fiv.size()) {
dbug("fileinfo", [&]() {
std::cerr << "Un-registering unknown fd:" << fd << "!" << std::endl;
Expand Down Expand Up @@ -249,6 +255,10 @@ const char *my_filename(File fd) {
DBUG_TRACE;
if (fivp == nullptr) return "<nullptr fivp>";

if (fd >= WS_START_FD) {
return my_ws_filename(fd);
}

const FileInfoVector &fiv = *fivp;
MUTEX_LOCK(g, &THR_LOCK_open);
if (fd < 0 || fd >= static_cast<int>(fiv.size())) {
Expand Down
15 changes: 15 additions & 0 deletions mysys/my_wsfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class WSBaseFile {
virtual int ws_sync() = 0;
virtual int ws_fsync() = 0;

const std::string &ws_uri() const { return wsenv_uri; }

protected:
// uri format: {wsenv_uri_prefix}/{wsenv_cluster}/{file}
std::string wsenv_uri;
Expand Down Expand Up @@ -462,4 +464,17 @@ size_t my_ws_write(File fd, const uchar *buffer, size_t count) {
return result;
}

const char *my_ws_filename(File fd) {
mysql_rwlock_rdlock(&ws_current_fd_lock);
auto grd =
create_scope_guard([]() { mysql_rwlock_unlock(&ws_current_fd_lock); });
auto iter = ws_file_map.find(fd);
// Return error if fd is not present
if (iter == ws_file_map.end()) {
errno = EINVAL;
return "<Unknown WS FD>";
}
return iter->second->ws_uri().c_str();
}

void MyWSFileEnd() { ws_file_map.clear(); }
9 changes: 9 additions & 0 deletions mysys/my_wsfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,12 @@ my_off_t my_ws_tell(File fd);
On failure, -1
*/
size_t my_ws_write(File fd, const uchar *buffer, size_t Count);

/**
Retrieve filename(URI) for specified fd
returns
On success, WSEnv URI
On failure, "Unknown WS FD"
*/
const char *my_ws_filename(File fd);

0 comments on commit 992265e

Please sign in to comment.