Bug #15547 | Can't initialize character set latin1 (path: /usr/share/mysql/charsets/) | ||
---|---|---|---|
Submitted: | 7 Dec 2005 9:06 | Modified: | 29 Jun 2007 16:42 |
Reporter: | Philippe Jalaber | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | Connector / ODBC | Severity: | S1 (Critical) |
Version: | 3.51 | OS: | Linux (Linux) |
Assigned to: | Bogdan Degtyariov | CPU Architecture: | Any |
[7 Dec 2005 9:06]
Philippe Jalaber
[7 Dec 2005 10:52]
Aleksey Kishkin
Philippe, I ran your example and it works fine for me.
[7 Dec 2005 10:57]
Aleksey Kishkin
The strange thing is - if you build mysql and myodbc from sources, the Index.xml must be in the /usr/local/mysql/share/mysql/charsets. The fact you program finds it in the /usr/share/mysql/charsets/ makes me believe you have other mysql libraries (than you build from sources). Could you provide here output of ldd test
[7 Dec 2005 11:16]
Aleksey Kishkin
I meant of course output of ldd /usr/local/lib/libmyodbc3.so
[9 Dec 2005 9:36]
Philippe Jalaber
I made a mistake. I did not build from tarballs but I used rpm packages. My myODBC driver has mysqlclient linked as static, I 'm sure that I link with right version. I made the same test with shared library but the result is the same ;( Please make sure that you run the test program in infinite loop, because it doesn't fail immediately.
[12 Dec 2005 17:17]
Aleksey Kishkin
Yes, I was able to reproduce it. $ while ( true ); do ./test $i > /dev/null ; done Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Segmentation fault Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file (1) HYT00:2019:[unixODBC][MySQL][ODBC 3.51 Driver]Can't initialize character set latin1 (path: /usr/local/mysql/share/mysql/charsets/) Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file (1) HYT00:2019:[unixODBC][MySQL][ODBC 3.51 Driver]Can't initialize character set latin1 (path: /usr/local/mysql/share/mysql/charsets/) Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file (1) HYT00:2019:[unixODBC][MySQL][ODBC 3.51 Driver]Can't initialize character set latin1 (path: /usr/local/mysql/share/mysql/charsets/) Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file (1) HYT00:2019:[unixODBC][MySQL][ODBC 3.51 Driver]Can't initialize character set latin1 (path: /usr/local/mysql/share/mysql/charsets/) Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Segmentation fault Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Segmentation fault Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file Character set 'latin1' is not a compiled character set and is not specified in the '/usr/local/mysql/share/mysql/charsets/Index.xml' file (1) HYT00:2019:[unixODBC][MySQL][ODBC 3.51 Driver]Can't initialize character set latin1 (path: /usr/local/mysql/share/mysql/charsets/) (1) HYT00:2019:[unixODBC][MySQL][ODBC 3.51 Driver]Can't initialize character set latin1 (path: /usr/local/mysql/share/mysql/charsets/) (1) HYT00:2019:[unixODBC][MySQL][ODBC 3.51 Driver]Can't initialize character set latin1 (path: /usr/local/mysql/share/mysql/charsets/) (1) HYT00:2019:[unixODBC][MySQL][ODBC 3.51 Driver]Can't initialize character set latin1 (path: /usr/local/mysql/share/mysql/charsets/)
[31 Mar 2006 13:15]
Pierre MARC
Have the same trouble on linux RedHat entreprise 4. I cannot make the MyOdbc driver run correctly in a multithread environment. I wrote also a little test program. sometimes it runs, sometimes it fails with the "Character set 'latin1' ..." message, sometimes it fails with a segmentation fault. I used MySql 5.0.19, MyOdbc 3.51.12 and UnixOdbc 2.2.11. My ODBC DSN uses the /usr/lib/libmyodbc3_r.so. I also tried recompiling myodbc but the compilation failed with error telling that there are multiple definition of adler32. Is there any workarround to that blocking situation ? to reproduce the pb: testodbc -s sourcename -u user -p password -h numthreads Here is the source of my testodbc program: #include <pthread.h> #include <stdio.h> #include <sql.h> // core #include <sqlext.h> // extensions #include <string> using namespace std; // Thread mutex pthread_mutex_t m_mMutex; // End Thread flag int EndThread = 0; int NumErrors = 0; // Num threads int NumThreads = 1; SQLCHAR Source[255]; // Data source name SQLCHAR User[255]; // Data source user SQLCHAR Password[255]; // Data source password SQLCHAR Table[255]; // Data source table void DisplaySqlError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt); int DisplaySqlStringInfo(SQLHENV henv, SQLHDBC hdbc, SQLUSMALLINT InfoType); int DoConnect(bool WithInfo, bool WithSearch); void* ThreadMain(void *Value); int main(int argc, char* argv[]) { if(argc <=1) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } Source[0] = '\0'; User[0] = '\0'; Password[0] = '\0'; int i; for(i=1;i<argc;i++) { if(strcmp(argv[i], "-s") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; strcpy((char *) Source, argv[i]); } else if(strcmp(argv[i], "-u") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; strcpy((char *) User, argv[i]); } else if(strcmp(argv[i], "-p") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; strcpy((char *) Password, argv[i]); } else if(strcmp(argv[i], "-t") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; strcpy((char *) Table, argv[i]); } else if(strcmp(argv[i], "-h") == 0) { if(i==(argc-1)) { printf("usage: testodbc -s DataSource -u User [-p Password] [-t Table] [-h NumThreads]\n"); return 0; } i++; NumThreads = atoi(argv[i]); if(NumThreads <= 0) NumThreads = 1; if(NumThreads > 500) NumThreads = 500; } } if(!DoConnect(true, false)) return 0; pthread_mutex_init(&m_mMutex, NULL); EndThread = NumThreads; int EndThreadHere = EndThread; for(i=0;i<NumThreads;i++) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); // the unix thread has a system scope for best performances pthread_t thid; pthread_create(&thid, &attr, ThreadMain, NULL); pthread_attr_destroy(&attr); } while(EndThreadHere) { pthread_mutex_lock(&m_mMutex); EndThreadHere = EndThread; pthread_mutex_unlock(&m_mMutex); } if(NumErrors) printf("\nProgram terminated with %d errors\n", NumErrors); else printf("\nProgram terminated successfully\n"); pthread_mutex_unlock(&m_mMutex); pthread_mutex_destroy(&m_mMutex); return 0; } void* ThreadMain(void *Value) { int RetVal = DoConnect(false, true); pthread_mutex_lock(&m_mMutex); if(!RetVal) NumErrors++; EndThread--; pthread_mutex_unlock(&m_mMutex); pthread_detach(pthread_self()); pthread_exit(NULL); return (void *)(0); // end of thread (unix) } int DoConnect(bool WithInfo, bool WithSearch) { SQLHENV henv; /* environment handle */ SQLHDBC hdbc; /* connection handle */ SQLHSTMT hstmt; /* statement handle */ SQLRETURN retcode; /* return code */ SQLCHAR SQLStmt[255]; henv = NULL; hdbc = NULL; hstmt = NULL; retcode = SQLAllocEnv(&henv); retcode = SQLAllocConnect(henv, &hdbc); retcode = SQLConnect(hdbc, Source, SQL_NTS, User, SQL_NTS, Password, SQL_NTS); if (retcode != SQL_SUCCESS) { printf("*** Cannot connect data source\n"); DisplaySqlError(henv, hdbc, hstmt); SQLFreeConnect(hdbc); SQLFreeEnv(henv); return 0; } if(WithInfo) { printf("Database name: "); DisplaySqlStringInfo(henv, hdbc,SQL_DBMS_NAME); printf("\nDatabase version: "); DisplaySqlStringInfo(henv, hdbc,SQL_DBMS_VER); printf("\nDriver name: "); DisplaySqlStringInfo(henv, hdbc,SQL_DRIVER_NAME); printf("\nDriver version: "); DisplaySqlStringInfo(henv, hdbc,SQL_DRIVER_VER); printf("\nDriver ODBC version: "); DisplaySqlStringInfo(henv, hdbc,SQL_ODBC_VER); printf("\n"); } if(WithSearch) { if(strlen((char *)Table)) { retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc,&hstmt); if (retcode == SQL_SUCCESS) { strcpy((char *)SQLStmt, "SELECT * FROM "); strcat((char *)SQLStmt, (char *)Table); retcode = SQLExecDirect(hstmt, SQLStmt, SQL_NTS); // Display The Results Of The SQL Query if (retcode == SQL_SUCCESS) printf("Database search successful\n"); else { printf("*** Error searching database\n"); DisplaySqlError(henv, hdbc, hstmt); SQLDisconnect(hdbc); SQLFreeConnect(hdbc); SQLFreeEnv(henv); return 0; } } // Free The SQL Statement Handle if(hstmt != NULL) SQLFreeHandle(SQL_HANDLE_STMT, hstmt); } } SQLDisconnect(hdbc); SQLFreeConnect(hdbc); SQLFreeEnv(henv); return 1; } void DisplaySqlError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt) { SQLCHAR Message[SQL_MAX_MESSAGE_LENGTH + 1]; SQLCHAR State[10]; SQLINTEGER NativeError; SQLSMALLINT TextLength; Message[0] = '\0'; SQLError(henv, hdbc, hstmt, State, &NativeError, Message, SQL_MAX_MESSAGE_LENGTH+1, &TextLength); printf("SQL error: %s\n", (const char *)Message); } int DisplaySqlStringInfo(SQLHENV henv, SQLHDBC hdbc, SQLUSMALLINT InfoType) { SQLRETURN retcode; /* return code */ SQLCHAR info[255]; /* info string for SQLGetInfo */ SQLSMALLINT cbInfoValue; info[0] = '\0'; retcode = SQLGetInfo(hdbc,InfoType, &info, sizeof(info),&cbInfoValue); if (retcode == SQL_SUCCESS) printf((const char *)info); else { printf("*** Cannot get info from data source\n"); DisplaySqlError(henv, hdbc, NULL); return 0; } return 1; } makefile: CXX = g++ CXXFLAGS = -I- -I./ -D_REENTRANT -D_GNU_SOURCE -DLINUX LDFLAGS = -L./ -lpthread -ldl -lodbc testodbc :: testodbc.o $(CXX) -o $@ $^ $(LDFLAGS) strip $@ testodbc.o : testodbc.cpp $(CXX) -c -o $@ $< $(CXXFLAGS)
[26 Apr 2006 15:57]
Xu Yuefu
Philippe, I tested your code, the result is: On my redhat9 system (libc-2.3.2, libpthread-0.29), it works fine. But on the other system (libc-2.3.4, libpthread-2.3.4), the same situation arise s just as yours. I am not very sure if it is related to the libc version ?
[7 Jul 2007 0:33]
Kent Boortz
I tried reproduce the initial problem using both test snippets in the bug report (with minor modifications), and tried it on SLES9 x86, RHEL4 x86 and x86_64, and could not reproduce the problem. I did hit another bug#25621, but it is unrelated. But I could repeat the craches with segmentation faults reported, especially on RHEL4 x86, so this bug report is left open.
[7 Jul 2007 17:39]
Jim Winstead
The library initialization in Connector/ODBC 3.51 is not very thread-safe on non-Windows platforms. A work-around is to make sure you start up one thread before the others, to avoid the race conditions. To fix this, we'll need to use pthread_once() on non-Windows platforms to make sure we only do the library initialization once, use a mutex-protected count of threads so we can shut the driver down at the right time, and make sure to call mysql_thread_init() in each new thread.
[7 Dec 2007 10:40]
Tonci Grgin
Bug#6536 was marked as duplicate of this one.
[23 Nov 2009 21:59]
Jim Winstead
Bug #45058 is a related bug in libmysql -- once that fix propagates, we can use the same new pthread_once() functionality to protect C/ODBC's init.
[30 May 2013 12:42]
Bogdan Degtyariov
Still doesn't seem to be fixed.
[1 Apr 2014 17:49]
Sri Ved
Any update on this one? One of our perl scripts using the following Perl libraries started seg-faulting and dumping core due to this error: DBI: 1.623 DBD::mysql: 4.022 OS: Cent OS 6.4 I know these are slightly older versions, but we are waiting for this bug to be fixed so we can upgrade.