diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-09-05 10:09:03 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-09-05 10:09:03 +0300 |
commit | 3c7887a85f2ed628aee28bf586c2ed115fe47186 (patch) | |
tree | 96ad0509425d372e846bdb23b0a729792fc3cbd6 | |
parent | 84813c396afc93dffe91d3a246d3a21e05eec488 (diff) | |
parent | 244fdc435da364aea3b6e55835115cc04fe3297f (diff) | |
download | mariadb-git-3c7887a85f2ed628aee28bf586c2ed115fe47186.tar.gz |
Merge 10.5 into 10.6
-rw-r--r-- | cmake/os/WindowsCache.cmake | 5 | ||||
-rw-r--r-- | config.h.cmake | 6 | ||||
-rw-r--r-- | mysys/my_gethwaddr.c | 2 | ||||
-rw-r--r-- | plugin/disks/CMakeLists.txt | 21 | ||||
-rw-r--r-- | plugin/disks/information_schema_disks.cc | 230 | ||||
-rw-r--r-- | plugin/disks/mysql-test/disks/disks.result | 4 | ||||
-rw-r--r-- | plugin/disks/mysql-test/disks/disks.test | 1 | ||||
-rw-r--r-- | storage/innobase/log/log0recv.cc | 12 | ||||
-rw-r--r-- | storage/innobase/page/page0cur.cc | 2 |
9 files changed, 220 insertions, 63 deletions
diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake index a5f808c8d2c..6cd19262a3c 100644 --- a/cmake/os/WindowsCache.cmake +++ b/cmake/os/WindowsCache.cmake @@ -63,6 +63,10 @@ SET(HAVE_GETHOSTBYADDR_R CACHE INTERNAL "") SET(HAVE_GETHRTIME CACHE INTERNAL "") SET(HAVE_GETPAGESIZE CACHE INTERNAL "") SET(HAVE_GETPASS CACHE INTERNAL "") +SET(HAVE_GETMNTENT CACHE INTERNAL "") +SET(HAVE_GETMNTENT_IN_SYS_MNTAB CACHE INTERNAL "") +SET(HAVE_GETMNTINFO CACHE INTERNAL "") +SET(HAVE_GETMNTINFO64 CACHE INTERNAL "") SET(HAVE_GETPASSPHRASE CACHE INTERNAL "") SET(HAVE_GETPWNAM CACHE INTERNAL "") SET(HAVE_GETPWUID CACHE INTERNAL "") @@ -145,6 +149,7 @@ SET(HAVE_SELECT 1 CACHE INTERNAL "") SET(HAVE_SELECT_H CACHE INTERNAL "") SET(HAVE_SETENV CACHE INTERNAL "") SET(HAVE_SETLOCALE 1 CACHE INTERNAL "") +SET(HAVE_SETMNTENT CACHE INTERNAL "") SET(HAVE_SIGACTION CACHE INTERNAL "") SET(HAVE_SIGINT 1 CACHE INTERNAL "") SET(HAVE_SIGPIPE CACHE INTERNAL "") diff --git a/config.h.cmake b/config.h.cmake index 568e0868d12..b58496a8a73 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -34,6 +34,11 @@ #cmakedefine HAVE_FLOAT_H 1 #cmakedefine HAVE_FNMATCH_H 1 #cmakedefine HAVE_FPU_CONTROL_H 1 +#cmakedefine HAVE_GETMNTENT 1 +#cmakedefine HAVE_GETMNTENT_IN_SYS_MNTAB 1 +#cmakedefine HAVE_GETMNTINFO 1 +#cmakedefine HAVE_GETMNTINFO64 1 +#cmakedefine HAVE_GETMNTINFO_TAKES_statvfs 1 #cmakedefine HAVE_GRP_H 1 #cmakedefine HAVE_IA64INTRIN_H 1 #cmakedefine HAVE_IEEEFP_H 1 @@ -208,6 +213,7 @@ #cmakedefine HAVE_SELECT 1 #cmakedefine HAVE_SETENV 1 #cmakedefine HAVE_SETLOCALE 1 +#cmakedefine HAVE_SETMNTENT 1 #cmakedefine HAVE_SETUPTERM 1 #cmakedefine HAVE_SIGSET 1 #cmakedefine HAVE_SIGACTION 1 diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index 0fa4fb2f995..6bba553a549 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -111,7 +111,7 @@ my_bool my_gethwaddr(uchar *to) for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++) { #if !defined(_AIX) || !defined(__linux__) -#if defined(__linux___) +#if defined(__linux__) #define HWADDR_DATA ifr[i].ifr_hwaddr.sa_data #else #define HWADDR_DATA ifr[i].ifr_hwaddr diff --git a/plugin/disks/CMakeLists.txt b/plugin/disks/CMakeLists.txt index d0f34b04027..4e40842cad0 100644 --- a/plugin/disks/CMakeLists.txt +++ b/plugin/disks/CMakeLists.txt @@ -1,7 +1,24 @@ INCLUDE (CheckIncludeFiles) -CHECK_INCLUDE_FILES ("sys/statvfs.h;mntent.h" INFO_HEADERS LANGUAGE CXX) -IF (INFO_HEADERS) +CHECK_SYMBOL_EXISTS (getmntent "mntent.h" HAVE_GETMNTENT) +CHECK_SYMBOL_EXISTS (getmntent "sys/mnttab.h" HAVE_GETMNTENT_IN_SYS_MNTAB) +CHECK_SYMBOL_EXISTS (setmntent "mntent.h" HAVE_SETMNTENT) +CHECK_SYMBOL_EXISTS (getmntinfo "sys/types.h;sys/mount.h" HAVE_GETMNTINFO) +CHECK_SYMBOL_EXISTS (getmntinfo64 "sys/types.h;sys/mount.h" HAVE_GETMNTINFO64) + +IF (HAVE_GETMNTINFO) +CHECK_CXX_SOURCE_COMPILES(" +#include <sys/types.h> +#include <sys/statvfs.h> +int main() +{ + struct statvfs *s; + return getmntinfo(&s, ST_WAIT); +} + " HAVE_GETMNTINFO_TAKES_statvfs) +ENDIF() +IF (HAVE_GETMNTENT OR HAVE_GETMNTENT_IN_SYS_MNTAB OR + HAVE_GETMNTINFO OR HAVE_GETMNTINFO64) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql) MYSQL_ADD_PLUGIN(DISKS information_schema_disks.cc MODULE_ONLY RECOMPILE_FOR_EMBEDDED) ENDIF() diff --git a/plugin/disks/information_schema_disks.cc b/plugin/disks/information_schema_disks.cc index 042cfaffaa4..174264c3269 100644 --- a/plugin/disks/information_schema_disks.cc +++ b/plugin/disks/information_schema_disks.cc @@ -17,11 +17,45 @@ #include <my_global.h> #include <sys/statvfs.h> #include <sys/types.h> +#if defined(HAVE_GETMNTENT) #include <mntent.h> +#elif !defined(HAVE_GETMNTINFO_TAKES_statvfs) +/* getmntinfo (the not NetBSD variants) */ +#include <sys/param.h> +#include <sys/ucred.h> +#include <sys/mount.h> +#endif +#if defined(HAVE_GETMNTENT_IN_SYS_MNTAB) +#include <sys/mnttab.h> +#define HAVE_GETMNTENT +#endif #include <sql_class.h> #include <sql_i_s.h> #include <sql_acl.h> /* check_global_access() */ +/* + This intends to support *BSD's, macOS, Solaris, AIX, HP-UX, and Linux. + + specificly: + FreeBSD/OpenBSD/DragonFly (statfs) NetBSD (statvfs) uses getmntinfo(). + macOS uses getmntinfo64(). + Linux can use getmntent_r(), but we've just used getmntent for simplification. + Linux/Solaris/AIX/HP-UX uses setmntent()/getmntent(). + Solaris uses getmntent() with a diffent prototype, return structure, and + no setmntent(fopen instead) +*/ +#if defined(HAVE_GETMNTINFO_TAKES_statvfs) || defined(HAVE_GETMNTENT) +typedef struct statvfs st_info; +#elif defined(HAVE_GETMNTINFO64) +typedef struct statfs64 st_info; +#else // GETMNTINFO +typedef struct statfs st_info; +#endif +#ifndef MOUNTED +/* HPUX - https://docstore.mik.ua/manuals/hp-ux/en/B2355-60130/getmntent.3X.html */ +#define MOUNTED MNT_MNTTAB +#endif + bool schema_table_store_record(THD *thd, TABLE *table); @@ -41,24 +75,40 @@ ST_FIELD_INFO disks_table_fields[]= }; - -int disks_table_add_row(THD* pThd, - TABLE* pTable, - const char* zDisk, - const char* zPath, - const struct statvfs& info) +static int disks_table_add_row_stat( + THD* pThd, + TABLE* pTable, + const char* zDisk, + const char* zPath, + const st_info &info) { // From: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/statvfs.h.html + // and same for statfs: + // From: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/statfs.2.html#//apple_ref/doc/man/2/statfs + // and: https://www.freebsd.org/cgi/man.cgi?query=statfs&sektion=2&apropos=0&manpath=FreeBSD+13.1-RELEASE+and+Ports // - // f_frsize Fundamental file system block size. + // f_bsize Fundamental file system block size. // f_blocks Total number of blocks on file system in units of f_frsize. // f_bfree Total number of free blocks. // f_bavail Number of free blocks available to non-privileged process. + ulong block_size= (ulong) info.f_bsize; - ulonglong total = ((ulonglong)info.f_frsize * info.f_blocks) / 1024; - ulonglong used = ((ulonglong)info.f_frsize * + ulonglong total = ((ulonglong) block_size * info.f_blocks) / 1024; + ulonglong used = ((ulonglong) block_size * (info.f_blocks - info.f_bfree)) / 1024; - ulonglong avail = ((ulonglong)info.f_frsize * info.f_bavail) / 1024; + ulonglong avail = ((ulonglong) block_size * info.f_bavail) / 1024; + + /* skip filesystems that don't have any space */ + if (!info.f_blocks) + return 0; + + /* skip RO mounted filesystems */ +#if defined(HAVE_GETMNTINFO_TAKES_statvfs) || defined(HAVE_GETMNTENT) + if (info.f_flag & ST_RDONLY) +#else + if (info.f_flags & MNT_RDONLY) +#endif + return 0; pTable->field[0]->store(zDisk, strlen(zDisk), system_charset_info); pTable->field[1]->store(zPath, strlen(zPath), system_charset_info); @@ -70,71 +120,147 @@ int disks_table_add_row(THD* pThd, return (schema_table_store_record(pThd, pTable) != 0) ? 1 : 0; } -int disks_table_add_row(THD* pThd, TABLE* pTable, const char* zDisk, const char* zPath) + +#ifdef HAVE_GETMNTENT +static int disks_table_add_row(THD* pThd, TABLE* pTable, const char* zDisk, const char* zPath) { int rv = 0; - struct statvfs info; + st_info info; if (statvfs(zPath, &info) == 0) // We ignore failures. { - rv = disks_table_add_row(pThd, pTable, zDisk, zPath, info); + rv = disks_table_add_row_stat(pThd, pTable, zDisk, zPath, info); } return rv; } +#endif + -int disks_fill_table(THD* pThd, TABLE_LIST* pTables, Item* pCond) +#ifdef HAVE_GETMNTINFO +static int disks_fill_table(THD* pThd, TABLE_LIST* pTables, Item* pCond) { - int rv = 1; - TABLE* pTable = pTables->table; + st_info *s; + int count, rv= 0; + TABLE* pTable= pTables->table; if (check_global_access(pThd, FILE_ACL, true)) - return 0; + return 0; + +#if defined(HAVE_GETMNTINFO_TAKES_statvfs) + count= getmntinfo(&s, ST_WAIT); +#elif defined(HAVE_GETMNTINFO64) + count= getmntinfo64(&s, MNT_WAIT); +#else + count= getmntinfo(&s, MNT_WAIT); +#endif + if (count == 0) + return 1; + + while (count && rv == 0) + { + rv= disks_table_add_row_stat(pThd, pTable, s->f_mntfromname, s->f_mntonname, *s); + count--; + s++; + } + return rv; +} +#else /* HAVE_GETMNTINFO */ + +static mysql_mutex_t m_getmntent; - FILE* pFile = setmntent("/etc/mtab", "r"); +/* HAVE_GETMNTENT */ +static int disks_fill_table(THD* pThd, TABLE_LIST* pTables, Item* pCond) +{ + int rv= 1; +#ifdef HAVE_SETMNTENT + struct mntent* pEnt; +#else + struct mnttab mnttabent, *pEnt= &mnttabent; +#endif + FILE* pFile; + TABLE* pTable= pTables->table; - if (pFile) + if (check_global_access(pThd, FILE_ACL, true)) + return 0; + +#ifdef HAVE_SETMNTENT + pFile= setmntent(MOUNTED, "r"); +#else + /* Solaris */ + pFile= fopen("/etc/mnttab", "r"); +#endif + + if (!pFile) + return 1; + + rv= 0; + + /* + We lock the outer loop rather than between getmntent so the multiple + infomation_schema.disks reads don't all start blocking each other and + no-one gets any answers. + */ + mysql_mutex_lock(&m_getmntent); + + while ((rv == 0) && +#if defined(HAVE_SETMNTENT) + (pEnt = getmntent(pFile)) + +#else + getmntent(pFile, pEnt) != 0 +#endif + ) { - const size_t BUFFER_SIZE = 4096; // 4K should be sufficient. - - char* pBuffer = new (std::nothrow) char [BUFFER_SIZE]; - - if (pBuffer) - { - rv = 0; - - struct mntent ent; - struct mntent* pEnt; - - while ((rv == 0) && (pEnt = getmntent_r(pFile, &ent, pBuffer, BUFFER_SIZE))) - { - // We only report the ones that refer to physical disks. - if (pEnt->mnt_fsname[0] == '/') - { - rv = disks_table_add_row(pThd, pTable, pEnt->mnt_fsname, pEnt->mnt_dir); - } - } - - delete [] pBuffer; - } - else - { - rv = 1; - } - - endmntent(pFile); + struct stat f; + const char *path, *point; +#ifdef HAVE_SETMNTENT + path= pEnt->mnt_dir; + point= pEnt->mnt_fsname; +#else + path= pEnt->mnt_mountp; + point= pEnt->mnt_special; +#endif + // Try to keep to real storage by excluding + // read only mounts, and mount points that aren't directories + if (hasmntopt(pEnt, MNTOPT_RO) != NULL) + continue; + if (stat(path, &f)) + continue; + if (!S_ISDIR(f.st_mode)) + continue; + rv= disks_table_add_row(pThd, pTable, point, path); } + mysql_mutex_unlock(&m_getmntent); + +#ifdef HAVE_SETMNTENT + endmntent(pFile); +#else + fclose(pFile); +#endif return rv; } +#endif /* HAVE_GETMNTINFO */ -int disks_table_init(void *ptr) +static int disks_table_init(void *ptr) { ST_SCHEMA_TABLE* pSchema_table = (ST_SCHEMA_TABLE*)ptr; pSchema_table->fields_info = disks_table_fields; pSchema_table->fill_table = disks_fill_table; +#ifndef HAVE_GETMNTINFO + mysql_mutex_init(0, &m_getmntent, MY_MUTEX_INIT_SLOW); +#endif + return 0; +} + +static int disks_table_deinit(void *ptr __attribute__((unused))) +{ +#ifndef HAVE_GETMNTINFO + mysql_mutex_destroy(&m_getmntent); +#endif return 0; } @@ -148,15 +274,15 @@ maria_declare_plugin(disks) MYSQL_INFORMATION_SCHEMA_PLUGIN, &disks_table_info, /* type-specific descriptor */ "DISKS", /* table name */ - "Johan Wikman", /* author */ + "Johan Wikman, Daniel Black", /* author */ "Disk space information", /* description */ PLUGIN_LICENSE_GPL, /* license type */ Show::disks_table_init, /* init function */ - NULL, /* deinit function */ - 0x0101, /* version = 1.1 */ + Show::disks_table_deinit, /* deinit function */ + 0x0102, /* version = 1.2 */ NULL, /* no status variables */ NULL, /* no system variables */ - "1.1", /* String version representation */ + "1.2", /* String version representation */ MariaDB_PLUGIN_MATURITY_STABLE /* Maturity (see include/mysql/plugin.h)*/ } mysql_declare_plugin_end; diff --git a/plugin/disks/mysql-test/disks/disks.result b/plugin/disks/mysql-test/disks/disks.result index eb78d4073df..38dfcf351a5 100644 --- a/plugin/disks/mysql-test/disks/disks.result +++ b/plugin/disks/mysql-test/disks/disks.result @@ -1,8 +1,8 @@ show create table information_schema.disks; Table Create Table DISKS CREATE TEMPORARY TABLE `DISKS` ( - `Disk` varchar(4096) NOT NULL, - `Path` varchar(4096) NOT NULL, + `Disk` varchar(pathlen) NOT NULL, + `Path` varchar(pathlen) NOT NULL, `Total` bigint(32) NOT NULL, `Used` bigint(32) NOT NULL, `Available` bigint(32) NOT NULL diff --git a/plugin/disks/mysql-test/disks/disks.test b/plugin/disks/mysql-test/disks/disks.test index 13a0762ae01..7189c548342 100644 --- a/plugin/disks/mysql-test/disks/disks.test +++ b/plugin/disks/mysql-test/disks/disks.test @@ -1,2 +1,3 @@ +--replace_regex /varchar\([0-9]+\)/varchar(pathlen)/ show create table information_schema.disks; select sum(Total) > sum(Available), sum(Total)>sum(Used) from information_schema.disks; diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index f584e929480..7db0fdbefa5 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -217,7 +217,9 @@ public: /** The page was modified, affecting the encryption parameters */ APPLIED_TO_ENCRYPTION, /** The page was modified, affecting the tablespace header */ - APPLIED_TO_FSP_HEADER + APPLIED_TO_FSP_HEADER, + /** The page was found to be corrupted */ + APPLIED_CORRUPTED, }; /** Apply log to a page frame. @@ -299,12 +301,10 @@ public: ut_ad(*l == OPT_PAGE_CHECKSUM); if (page_checksum(block, l + 1)) { - applied= APPLIED_YES; page_corrupted: sql_print_error("InnoDB: Set innodb_force_recovery=1" " to ignore corruption."); - recv_sys.set_corrupt_log(); - return applied; + return APPLIED_CORRUPTED; } goto next_after_applying; } @@ -2805,6 +2805,7 @@ static buf_block_t *recv_recover_page(buf_block_t *block, mtr_t &mtr, start_lsn = 0; continue; case log_phys_t::APPLIED_YES: + case log_phys_t::APPLIED_CORRUPTED: goto set_start_lsn; case log_phys_t::APPLIED_TO_FSP_HEADER: case log_phys_t::APPLIED_TO_ENCRYPTION: @@ -2858,7 +2859,8 @@ static buf_block_t *recv_recover_page(buf_block_t *block, mtr_t &mtr, } set_start_lsn: - if (recv_sys.is_corrupt_log() && !srv_force_recovery) { + if ((a == log_phys_t::APPLIED_CORRUPTED + || recv_sys.is_corrupt_log()) && !srv_force_recovery) { if (init) { init->created = false; if (space || block->page.id().page_no()) { diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index 5f7192675dc..3f863d36a3a 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -1648,7 +1648,7 @@ inc_dir: { const byte *r= rec; const byte *c= cur->rec; - const byte *c_end= cur->rec + data_size; + const byte *c_end= c + (page_rec_is_infimum(c) ? 8 : data_size); static_assert(REC_N_OLD_EXTRA_BYTES == REC_N_NEW_EXTRA_BYTES + 1, ""); if (c <= insert_buf && c_end > insert_buf) c_end= insert_buf; |