File:  [LON-CAPA] / doc / build / Attic / loncapasqldatabase.html
Revision 1.10: download - view: text, annotated - select for diffs
Wed Feb 14 15:24:16 2001 UTC (23 years, 4 months ago) by harris41
Branches: MAIN
CVS tags: HEAD
forgot some steps with Msql-Mysql.. -Scott

    1: <HTML>
    2: <HEAD>
    3: <TITLE>LON-CAPA SQL Database Documentation</TITLE>
    4: </HEAD>
    5: <BODY>
    6: <H1>LON-CAPA SQL Database Documentation</H1>
    7: <P>
    8: Scott Harrison
    9: </P>
   10: <P>
   11: Last updated: 02/14/2001
   12: </P>
   13: <P>
   14: This file describes issues associated with LON-CAPA
   15: and a SQL database.
   16: </P>
   17: <H2>Latest HOWTO</H2>
   18: <P>
   19: <UL>
   20: <LI>Important notes
   21: <LI>Current status of documentation</LI>
   22: <LI>Current status of implementation</LI>
   23: <LI>Purpose within LON-CAPA</LI>
   24: <LI>Dependencies</LI>
   25: <LI>Installation</LI>
   26: <LI>Installation from source</LI>
   27: <LI>Configuration (automated)</LI>
   28: <LI>Manual configuration</LI>
   29: <LI>Testing</LI>
   30: <LI>Example sections of code relevant to LON-CAPA</LI>
   31: </UL>
   32: </P>
   33: <H2>Important notes</H2>
   34: <P>
   35: It might be worthwhile to look at /usr/local/mysql/manual.html.
   36: It is quite in depth.
   37: </P>
   38: <H2>Current status of documentation</H2>
   39: <P>
   40: I am going to begin documentation by inserting what notes
   41: I have into this file.  I will be subsequently rearranging
   42: them and editing them based on the tests that I conduct.
   43: I am trying to make sure that documentation, installation,
   44: and run-time issues are all consistent and correct.  The
   45: current status of everything is that it works and has
   46: been minimally tested, but things need to be cleaned up
   47: and checked again!
   48: </P>
   49: <H2>Current status of implementation</H2>
   50: <P>
   51: Need to
   52: <UL>
   53: <LI>Installation: Fix binary file listings for user permissions and ownership.
   54: <LI>Installation: Make sure sql server starts, and if database does not
   55: exist, then create. (/etc/rc.d).
   56: <LI>Processes: Make sure loncron initiates lonsql on library machines.
   57: <LI>Read in metadata from right place periodically.
   58: <LI>Implement tested perl module handler.
   59: </UL>
   60: <P>
   61: Right now, a lot of "feasibility" work has been done.
   62: Recipes for manual installation and configuration have
   63: been gathered.  Network connectivity of lond->lonsql->lond->lonc
   64: type tests have been performed.  A binary installation
   65: has been compiled in an RPM (LON-CAPA-mysql, with perl components
   66: a part of LON-CAPA-systemperl).
   67: The most lacking test in terms of feasibility has
   68: been looking at benchmarks to analyze the load at which
   69: the SQL database can efficiently allow many users to
   70: make simultaneous requests of the metadata database.
   71: </P>
   72: <P>
   73: Documentation has been pieced together over time.  But,
   74: as mentioned in the previous section, it needs an
   75: overhaul.
   76: </P>
   77: <P>
   78: The binary installation has some quirks associated with it.
   79: Some of the user permissions are wrong, although this is
   80: benign.  Also, other options of binary installation (such
   81: as using binary RPMs put together by others) were dismissed
   82: given the difficulty of getting differing combinations of
   83: these external RPMs to work together.
   84: </P>
   85: <P>
   86: Most configuration questions have been initially worked out
   87: to the point of getting this SQL software component working,
   88: however there may be more optimal approaches than currently
   89: exist.
   90: </P>
   91: <H2>Purpose within LON-CAPA</H2>
   92: <P>
   93: LON-CAPA is meant to distribute A LOT of educational content
   94: to A LOT of people.  It is ineffective to directly rely on contents
   95: within the ext2 filesystem to be speedily scanned for 
   96: on-the-fly searches of content descriptions.  (Simply put,
   97: it takes a cumbersome amount of time to open, read, analyze, and
   98: close thousands of files.)
   99: </P>
  100: <P>
  101: The solution is to hash-index various data fields that are
  102: descriptive of the educational resources on a LON-CAPA server
  103: machine.  Descriptive data fields are referred to as
  104: "metadata".  The question then arises as to how this metadata
  105: is handled in terms of the rest of the LON-CAPA network
  106: without burdening client and daemon processes.  I now
  107: answer this question in the format of Problem and Solution
  108: below.
  109: </P>
  110: <P>
  111: <PRE>
  112: PROBLEM SITUATION:
  113: 
  114:   If Server A wants data from Server B, Server A uses a lonc process to
  115:   send a database command to a Server B lond process.
  116:     lonc= loncapa client process    A-lonc= a lonc process on Server A
  117:     lond= loncapa daemon process
  118: 
  119:                  database command
  120:     A-lonc  --------TCP/IP----------------> B-lond
  121: 
  122:   The problem emerges that A-lonc and B-lond are kept waiting for the
  123:   MySQL server to "do its stuff", or in other words, perform the conceivably
  124:   sophisticated, data-intensive, time-sucking database transaction.  By tying
  125:   up a lonc and lond process, this significantly cripples the capabilities
  126:   of LON-CAPA servers. 
  127: 
  128:   While commercial databases have a variety of features that ATTEMPT to
  129:   deal with this, freeware databases are still experimenting and exploring
  130:   with different schemes with varying degrees of performance stability.
  131: 
  132: THE SOLUTION:
  133: 
  134:   A separate daemon process was created that B-lond works with to
  135:   handle database requests.  This daemon process is called "lonsql".
  136: 
  137:   So,
  138:                 database command
  139:   A-lonc  ---------TCP/IP-----------------> B-lond =====> B-lonsql
  140:          <---------------------------------/                |
  141:            "ok, I'll get back to you..."                    |
  142:                                                             |
  143:                                                             /
  144:   A-lond  <-------------------------------  B-lonc   <======
  145:            "Guess what? I have the result!"
  146: 
  147:   Of course, depending on success or failure, the messages may vary,
  148:   but the principle remains the same where a separate pool of children
  149:   processes (lonsql's) handle the MySQL database manipulations.
  150: </PRE>
  151: </P>
  152: <H2>Dependencies</H2>
  153: <P>
  154: I believe (but am not 100% confident) that the following
  155: RPMs are necessary (in addition to the current ones
  156: in rpm_list.txt) to run MySQL.  Basically I discovered these
  157: dependencies while trying to do external RPM based installs.
  158: I assume, and sometimes found, that these dependencies apply
  159: to tarball-based distributions too.  (So to play it on the
  160: safe side, I am going to include these RPMs as part of the
  161: core, minimal RPM set.)
  162: <UL>
  163: <LI>egcs-1.1.2-30</LI>
  164: <LI>cpp-1.1.2-30</LI>
  165: <LI>glibc-devel-2.1.3-15</LI>
  166: <LI>zlib-devel-1.1.3-6</LI>
  167: </UL>
  168: </P>
  169: <H2>Installation</H2>
  170: <P>
  171: Installation of the LON-CAPA SQL database normally occurs
  172: by default when using the LON-CAPA installation CD
  173: (see http://install.lon-capa.org).  It is installed
  174: as the LON-CAPA-mysql RPM.  This RPM encodes for the MySQL
  175: engine.  Related perl interfaces (Perl::DBI, Perl::Msql-Mysql)
  176: are encoded in the LON-CAPA-systemperl RPM.
  177: </P>
  178: <P>
  179: The three components of a MySQL installation for the
  180: LON-CAPA system are further described immediately below.
  181: <TABLE BORDER="0">
  182: <TR><TD COLSPAN="2"><STRONG>Perl::DBI module</STRONG>-
  183: the API "front-end"...</TD></TR>
  184: <TR><TD WIDTH="10%"></TD><TD>database interface module for organizing generic
  185: database commands which are independent of specific
  186: database implementation (such as MySQL, mSQL, Postgres, etc).
  187: </TD></TR>
  188: <TR><TD COLSPAN="2"><STRONG>Perl::MySQL module</STRONG>-
  189: the API "mid-section"...</TD></TR>
  190: <TR><TD WIDTH="10%"></TD><TD>the module to directly interface with the actual
  191: MySQL database engine</TD></TR>
  192: <TR><TD COLSPAN="2"><STRONG>MySQL database engine</STRONG>-
  193: the "back-end"...</TD></TR>
  194: <TR><TD WIDTH="10%"></TD><TD>the binary installation (compiled either
  195: from source or pre-compiled file listings) which provides the
  196: actual MySQL functionality on the system</TD></TR>
  197: </TABLE>
  198: </P>
  199: <H2>Installation from source</H2>
  200: <P>
  201: Note: the mysql site recommends that Linux users install by
  202: using the MySQL RPMs (MySQL-client, MySQL, MySQL-shared, etc).
  203: While these RPMs work, I was unsuccessful at integrating
  204: this RPM-installed database with perl modules from www.cpan.org.
  205: Hence, I <STRONG>strongly</STRONG> recommend that, when installing
  206: from "source", MySQL and the perl components be in fact installed
  207: from their tarballs (.tar.gz, .tgz).  (Perl components, when installed
  208: from RPMs, also wound up in incorrect locations on the disk.)
  209: Do not coordinate a source install with externally made RPMs!
  210: It is, of course, okay to use LON-CAPA RPMs such as LON-CAPA-systemperl
  211: and LON-CAPA-mysql since we, in fact, made these RPMs correctly :).
  212: <UL>
  213: <LI>http://www.cpan.org/authors/id/JWIED/Msql-Mysql-modules-1.2215.tar.gz
  214: <BR>This tarball Released 20th August 2000
  215: <LI>http://www.mysql.com/Downloads/MySQL-3.23/mysql-3.23.33-pc-linux-gnu-i686.tar.gz
  216: <BR>This tarball Last changed 2000-11-11
  217: <BR>This is actually a binary tarball (as opposed to source code
  218: that is subsequently compiled).
  219: <LI>http://www.cpan.org/authors/id/TIMB/DBI-1.14.tar.gz
  220: <BR>This tarball Released 14th June 2000
  221: </UL>
  222: </P>
  223: <P>So, here is exactly how I installed MySQL-3.23. (Note that all files
  224: wind up in /usr/local/mysql-3.23.33-pc-linux-gnu-i686 except for
  225: a link from /usr/local/mysql to /usr/local/mysql-3.23.33-pc-linux-gnu-i686
  226: and some files involved in system process handling (/etc/rc.d/*/*mysql).
  227: </P>
  228: <P>This is how I installed the Msql-Mysql-modules perl modules.
  229: <PRE>
  230: [root@fenchurch Msql-Mysql-modules-1.2215]# perl Makefile.PL 
  231: Which drivers do you want to install?
  232: 
  233:     1)	MySQL only
  234:     2)	mSQL only (either of mSQL 1 or mSQL 2)
  235:     3)  MySQL and mSQL (either of mSQL 1 or mSQL 2)
  236: 
  237:     4)  mSQL 1 and mSQL 2
  238:     5)  MySQL, mSQL 1 and mSQL 2
  239: 
  240: Enter the appropriate number:  [3] 1
  241: 
  242: 
  243: Do you want to install the MysqlPerl emulation? You might keep your old
  244: Mysql module (to be distinguished from DBD::mysql!) if you are concerned
  245: about compatibility to existing applications! [y] n
  246: Where is your MySQL installed? Please tell me the directory that
  247: contains the subdir 'include'. [/usr/local/mysql] 
  248: Which database should I use for testing the MySQL drivers? [test] 
  249: On which host is database test running (hostname, ip address
  250: or host:port) [localhost] 
  251: [root@fenchurch Msql-Mysql-modules-1.2215]# make
  252: [root@fenchurch Msql-Mysql-modules-1.2215]# make test
  253: make[1]: Entering directory `/home/user/Msql-Mysql-modules-1.2215/mysql'
  254: make[1]: Leaving directory `/home/user/Msql-Mysql-modules-1.2215/mysql'
  255: make[1]: Entering directory `/home/user/Msql-Mysql-modules-1.2215/mysql'
  256: PERL_DL_NONLAZY=1 /usr/bin/perl -I../blib/arch -I../blib/lib -I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503 -e 'use Test::Harness qw(&runtests $verbose); $verbose=0; runtests @ARGV;' t/*.t
  257: t/00base............ok
  258: t/10dsnlist.........ok
  259: t/20createdrop......ok
  260: t/30insertfetch.....ok
  261: t/40bindparam.......ok
  262: t/40blobs...........ok
  263: t/40listfields......ok
  264: t/40nulls...........ok
  265: t/40numrows.........ok
  266: t/50chopblanks......ok
  267: t/50commit..........ok
  268: t/60leaks...........skipping test on this platform
  269: t/ak-dbd............ok
  270: t/akmisc............ok
  271: t/dbdadmin..........ok
  272: t/mysql.............ok
  273: t/mysql2............ok
  274: All tests successful, 1 test skipped.
  275: Files=17,  Tests=732, 40 wallclock secs (15.38 cusr +  1.30 csys = 16.68 CPU)
  276: [root@fenchurch Msql-Mysql-modules-1.2215]# make install
  277: 
  278: These files are installed.
  279: /usr/bin/dbimon
  280: /usr/lib/perl5/man/man3/Bundle::DBD::mysql.3
  281: /usr/lib/perl5/man/man3/DBD::mysql.3
  282: /usr/lib/perl5/man/man3/Mysql.3
  283: /usr/lib/perl5/site_perl/5.005/i386-linux/Bundle/DBD/mysql.pm
  284: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/mysql.pm
  285: /usr/lib/perl5/site_perl/5.005/i386-linux/Mysql.pm
  286: /usr/lib/perl5/site_perl/5.005/i386-linux/Mysql/Statement.pm
  287: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBD/mysql/mysql.bs
  288: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBD/mysql/mysql.so
  289: /usr/man/man1/dbimon.1
  290: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/Msql-Mysql-modules/.packlist
  291: </PRE>
  292: </P>
  293: <P>
  294: This is how I installed the DBI perl modules.
  295: <PRE>
  296: [root@fenchurch DBI-1.14]# perl Makefile.PL
  297: *** Note:
  298:     The optional PlRPC-modules (RPC::PlServer etc) are not installed.
  299:     If you want to use the DBD::Proxy driver and DBI::ProxyServer
  300:     modules, then you'll need to install the RPC::PlServer, RPC::PlClient,
  301:     Storable and Net::Daemon modules. The CPAN Bundle::DBI may help you.
  302:     You can install them any time after installing the DBI.
  303:     You do *not* need these modules for typical DBI usage.
  304: 
  305: Optional modules are available from any CPAN mirror, in particular
  306:     http://www.perl.com/CPAN/modules/by-module
  307:     http://www.perl.org/CPAN/modules/by-module
  308:     ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/by-module
  309: 
  310: Checking if your kit is complete...
  311: Looks good
  312: Writing Makefile for DBI
  313: 
  314:     Remember to actually *read* the README file!
  315:     Use  'make' to build the software (dmake or nmake on Windows).
  316:     Then 'make test' to execute self tests.
  317:     Then 'make install' to install the DBI and then delete this working
  318:     directory before unpacking and building any DBD::* drivers.
  319: 
  320: [root@fenchurch DBI-1.14]# make
  321: [root@fenchurch DBI-1.14]# make test
  322: PERL_DL_NONLAZY=1 /usr/bin/perl -Iblib/arch -Iblib/lib -I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503 -e 'use Test::Harness qw(&runtests $verbose); $verbose=0; runtests @ARGV;' t/*.t
  323: t/basics............ok
  324: t/dbidrv............ok
  325: t/examp.............ok
  326: t/meta..............ok
  327: t/proxy.............skipping test on this platform
  328: t/shell.............ok
  329: t/subclass..........ok
  330: All tests successful, 1 test skipped.
  331: Files=7,  Tests=179,  7 wallclock secs ( 6.46 cusr +  0.49 csys =  6.95 CPU)
  332: PERL_DL_NONLAZY=1 /usr/bin/perl -Iblib/arch -Iblib/lib -I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503 test.pl
  333: test.pl 
  334: DBI test application $Revision: 1.10 $
  335: Using /home/user/DBI-1.14/blib
  336: Switch: DBI 1.14 by Tim Bunce, 1.14
  337: Available Drivers: ADO, ExampleP, Multiplex, Proxy, mysql
  338: dbi:ExampleP:: testing 5 sets of 20 connections:
  339: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
  340: Disconnecting...
  341: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
  342: Disconnecting...
  343: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
  344: Disconnecting...
  345: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
  346: Disconnecting...
  347: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
  348: Disconnecting...
  349: Made 100 connections in  0 wallclock secs ( 0.22 usr +  0.03 sys =  0.25 CPU)
  350: 
  351: Testing handle creation speed...
  352: 5000 NullP statement handles cycled in 6.6 cpu+sys seconds (762 per sec)
  353: 
  354: test.pl done
  355: 
  356: [root@fenchurch DBI-1.14]# make install
  357: These files are installed.
  358: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/.packlist
  359: /usr/bin/dbiproxy
  360: /usr/bin/dbish
  361: /usr/lib/perl5/man/man3/Bundle::DBI.3
  362: /usr/lib/perl5/man/man3/DBD::ADO.3
  363: /usr/lib/perl5/man/man3/DBD::Multiplex.3
  364: /usr/lib/perl5/man/man3/DBD::Proxy.3
  365: /usr/lib/perl5/man/man3/DBI.3
  366: /usr/lib/perl5/man/man3/DBI::DBD.3
  367: /usr/lib/perl5/man/man3/DBI::FAQ.3
  368: /usr/lib/perl5/man/man3/DBI::Format.3
  369: /usr/lib/perl5/man/man3/DBI::ProxyServer.3
  370: /usr/lib/perl5/man/man3/DBI::Shell.3
  371: /usr/lib/perl5/man/man3/DBI::W32ODBC.3
  372: /usr/lib/perl5/man/man3/Win32::DBIODBC.3
  373: /usr/lib/perl5/site_perl/5.005/i386-linux/Bundle/DBI.pm
  374: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/ADO.pm
  375: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/ExampleP.pm
  376: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/Multiplex.pm
  377: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/NullP.pm
  378: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/Proxy.pm
  379: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/Sponge.pm
  380: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI.pm
  381: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/DBD.pm
  382: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/FAQ.pm
  383: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/Format.pm
  384: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/ProxyServer.pm
  385: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/Shell.pm
  386: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/W32ODBC.pm
  387: /usr/lib/perl5/site_perl/5.005/i386-linux/Win32/DBIODBC.pm
  388: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/DBI.bs
  389: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/DBI.so
  390: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/DBIXS.h
  391: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/Driver.xst
  392: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/dbd_xsh.h
  393: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/dbi_sql.h
  394: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/dbipport.h
  395: /usr/man/man1/dbiproxy.1
  396: /usr/man/man1/dbish.1
  397: </PRE>
  398: </P>
  399: <FONT COLOR="green"> old notes in green
  400: <P>
  401: The following set of tarballs was found to work together
  402: properly on a LON-CAPA RedHat 6.2 system:
  403: <UL>
  404: <LI>DBI-1.13.tar.gz
  405: <LI>Msql-Mysql-modules-1.2209.tar.gz
  406: <LI>mysql-3.22.32.tar.gz
  407: </UL>
  408: </P>
  409: <P>
  410: Installation was simply a matter of following the instructions
  411: and typing the several "make" commands for each 
  412: </P>
  413: </FONT>
  414: <H2>Configuration (automated)</H2>
  415: <P>
  416: Not yet developed.  This will be part of an interface
  417: present on LON-CAPA systems that can be launched by
  418: entering the command <TT>/usr/sbin/loncapaconfig</TT>.
  419: </P>
  420: <H2>Manual configuration</H2>
  421: <P>
  422: This is not complete.
  423: </P>
  424: <P>
  425: <STRONG>Starting the mysql daemon</STRONG>: Login on the Linux
  426: system as user 'www'.  Enter the command
  427: <TT>/usr/local/bin/safe_mysqld &</TT>
  428: </P>
  429: <P>
  430: <STRONG>Set a password for 'root'</STRONG>:
  431: <TT>/usr/local/bin/mysqladmin -u root password 'new-password'</TT>
  432: </P>
  433: <P>
  434: <STRONG>Adding a user</STRONG>:  Start the mysql daemon.  Login to the
  435: mysql system as root (<TT>mysql -u root -p mysql</TT>)
  436: and enter the right password (for instance 'newmysql').  Add the user
  437: www
  438: <PRE>
  439: INSERT INTO user (Host, User, Password)
  440: VALUES ('localhost','www',password('newmysql'));
  441: </PRE>
  442: </P>
  443: <P>
  444: <STRONG>Granting privileges to user 'www'</STRONG>:
  445: <PRE>
  446: GRANT ALL PRIVILEGES ON *.* TO www@localhost;
  447: FLUSH PRIVILEGES;
  448: </PRE>
  449: </P>
  450: <P>
  451: <STRONG>Set the SQL server to start upon system startup</STRONG>:
  452: Copy support-files/mysql.server to the right place on the system
  453: (/etc/rc.d/...).
  454: </P>
  455: <P>
  456: <STRONG>The Perl API</STRONG>
  457: <PRE>
  458:    $dbh = DBI->connect(	"DBI:mysql:loncapa",
  459: 			"www",
  460: 			"SOMEPASSWORD",
  461: 			{ RaiseError =>0,PrintError=>0});
  462: 
  463: There is an obvious need to CONNECT to the database, and in order to do
  464: this, there must be:
  465:   a RUNNING mysql daemon;
  466:   a DATABASE named "loncapa";
  467:   a USER named "www";
  468:   and an ABILITY for LON-CAPA on one machine to access
  469:        SQL database on another machine;
  470:   
  471: So, here are some notes on implementing these configurations.
  472: 
  473: ** RUNNING mysql daemon (safe_mysqld method)
  474: 
  475: The recommended way to run the MySQL daemon is as a non-root user
  476: (probably www)...
  477: 
  478: so, 1) login as user www on the linux machine
  479:     2) start the mysql daemon as /usr/local/bin/safe_mysqld &
  480: 
  481: safe_mysqld only works if the local installation of MySQL is set to the
  482: right directory permissions which I found to be:
  483: chown www:users /usr/local/var/mysql
  484: chown www:users /usr/local/lib/mysql
  485: chown -R www:users /usr/local/mysql
  486: chown www:users /usr/local/include/mysql
  487: chown www:users /usr/local/var
  488: 
  489: ** DATABASE named "loncapa"
  490: 
  491: As user www, run this command
  492:     mysql -u root -p mysql
  493: enter the password as SOMEPASSWORD
  494: 
  495: This allows you to manually enter MySQL commands.
  496: The MySQL command to generate the loncapa DATABASE is:
  497: 
  498: CREATE DATABASE 'loncapa';
  499: 
  500: ** USER named "www"
  501: 
  502: As user www, run this command
  503:     mysql -u root -p mysql
  504: enter the password as SOMEPASSWORD
  505: 
  506: To add the user www to the MySQL server, and grant all
  507: privileges on *.* to www@localhost identified by 'SOMEPASSWORD'
  508: with grant option;
  509: 
  510: INSERT INTO user (Host, User, Password)
  511: VALUES ('localhost','www',password('SOMEPASSWORD'));
  512: 
  513: GRANT ALL PRIVILEGES ON *.* TO www@localhost;
  514: 
  515: FLUSH PRIVILEGES;
  516: 
  517: ** ABILITY for LON-CAPA machines to communicate with SQL databases on
  518:    other LON-CAPA machines
  519: 
  520: An up-to-date lond and lonsql.
  521: </PRE>
  522: </P>
  523: <H2>Testing</H2>
  524: <P>
  525: <PRE>
  526: <STRONG>** TEST the database connection with my current tester.pl code
  527: which mimics what command will eventually be sent through lonc.</STRONG>
  528: 
  529: $reply=reply(
  530:     "querysend:SELECT * FROM general_information WHERE Id='AAAAA'",$lonID);
  531: </PRE>
  532: </P>
  533: <H2>Example sections of code relevant to LON-CAPA</H2>
  534: <P>
  535: Here are excerpts of code which implement the above handling:
  536: </P>
  537: <P>
  538: <PRE>
  539: <STRONG>**LONSQL
  540: A subroutine from "lonsql" which establishes a child process for handling
  541: database interactions.</STRONG>
  542: 
  543: sub make_new_child {
  544:     my $pid;
  545:     my $sigset;
  546:     
  547:     # block signal for fork
  548:     $sigset = POSIX::SigSet->new(SIGINT);
  549:     sigprocmask(SIG_BLOCK, $sigset)
  550:         or die "Can't block SIGINT for fork: $!\n";
  551:     
  552:     die "fork: $!" unless defined ($pid = fork);
  553:     
  554:     if ($pid) {
  555:         # Parent records the child's birth and returns.
  556:         sigprocmask(SIG_UNBLOCK, $sigset)
  557:             or die "Can't unblock SIGINT for fork: $!\n";
  558:         $children{$pid} = 1;
  559:         $children++;
  560:         return;
  561:     } else {
  562:         # Child can *not* return from this subroutine.
  563:         $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before
  564:     
  565:         # unblock signals
  566:         sigprocmask(SIG_UNBLOCK, $sigset)
  567:             or die "Can't unblock SIGINT for fork: $!\n";
  568: 	
  569: 	
  570:         #open database handle
  571: 	# making dbh global to avoid garbage collector
  572: 	unless (
  573: 		$dbh = DBI->connect("DBI:mysql:loncapa","www","SOMEPASSWORD",{ RaiseError =>0,PrintError=>0})
  574: 		) { 
  575: 	            my $st=120+int(rand(240));
  576: 		    &logthis("<font color=blue>WARNING: Couldn't connect to database  ($st secs): $@</font>");
  577: 		    print "database handle error\n";
  578: 		    sleep($st);
  579: 		    exit;
  580: 
  581: 	  };
  582: 	# make sure that a database disconnection occurs with ending kill signals
  583: 	$SIG{TERM}=$SIG{INT}=$SIG{QUIT}=$SIG{__DIE__}=\&DISCONNECT;
  584: 
  585:         # handle connections until we've reached $MAX_CLIENTS_PER_CHILD
  586:         for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
  587:             $client = $server->accept()     or last;
  588:             
  589:             # do something with the connection
  590: 	    $run = $run+1;
  591: 	    my $userinput = <$client>;
  592: 	    chomp($userinput);
  593: 	    	    
  594: 	    my ($conserver,$querytmp)=split(/&/,$userinput);
  595: 	    my $query=unescape($querytmp);
  596: 
  597:             #send query id which is pid_unixdatetime_runningcounter
  598: 	    $queryid = $thisserver;
  599: 	    $queryid .="_".($$)."_";
  600: 	    $queryid .= time."_";
  601: 	    $queryid .= $run;
  602: 	    print $client "$queryid\n";
  603: 	    
  604:             #prepare and execute the query
  605: 	    my $sth = $dbh->prepare($query);
  606: 	    my $result;
  607: 	    unless ($sth->execute())
  608: 	    {
  609: 		&logthis("<font color=blue>WARNING: Could not retrieve from database: $@</font>");
  610: 		$result="";
  611: 	    }
  612: 	    else {
  613: 		my $r1=$sth->fetchall_arrayref;
  614: 		my @r2; map {my $a=$_; my @b=map {escape($_)} @$a; push @r2,join(",", @b)} (@$r1);
  615: 		$result=join("&",@r2) . "\n";
  616: 	    }
  617:             &reply("queryreply:$queryid:$result",$conserver);
  618: 
  619:         }
  620:     
  621:         # tidy up gracefully and finish
  622: 	
  623:         #close the database handle
  624: 	$dbh->disconnect
  625: 	   or &logthis("<font color=blue>WARNING: Couldn't disconnect from database  $DBI::errstr ($st secs): $@</font>");
  626:     
  627:         # this exit is VERY important, otherwise the child will become
  628:         # a producer of more and more children, forking yourself into
  629:         # process death.
  630:         exit;
  631:     }
  632: }
  633: </P>
  634: <P>
  635: <STRONG>** LOND enabling of MySQL requests</STRONG>
  636: <BR />
  637: This code is part of every lond child process in the
  638: way that it parses command request syntax sent to it
  639: from lonc processes.  Based on the diagram above, querysend
  640: corresponds to B-lonc sending the result of the query.
  641: queryreply corresponds to B-lond indicating that it has
  642: received the request and will start the database transaction
  643: (it returns "ok" to
  644: A-lonc ($client)).
  645: <PRE>
  646: # ------------------------------------------------------------------- querysend
  647:                    } elsif ($userinput =~ /^querysend/) {
  648:                        my ($cmd,$query)=split(/:/,$userinput);
  649: 		       $query=~s/\n*$//g;
  650:                      print $client sqlreply("$hostid{$clientip}\&$query")."\n";
  651: # ------------------------------------------------------------------ queryreply
  652:                    } elsif ($userinput =~ /^queryreply/) {
  653:                        my ($cmd,$id,$reply)=split(/:/,$userinput); 
  654: 		       my $store;
  655:                        my $execdir=$perlvar{'lonDaemons'};
  656:                        if ($store=IO::File->new(">$execdir/tmp/$id")) {
  657: 			   print $store $reply;
  658: 			   close $store;
  659: 			   print $client "ok\n";
  660: 		       }
  661: 		       else {
  662: 			   print $client "error:$!\n";
  663: 		       }
  664: 
  665: </PRE>
  666: 
  667: </P>
  668: </BODY>
  669: </HTML>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>