Drupal shared database multi-site
Drupal allows you to run from multiple different databases by being creative with the use of the multi-site functionality built into core. Using multi-site in this method requires certain intentional design decisions.
Note, this method is no replacement for fault-tolerant redundancy through replication, but it will allow a difference of content management between a primary domain and subdomains with different priorities.
In this example, I will show how to run a single site through multiple different subdomains and setup a development environment separate from the live configuration. This site will have a www domain for edited articles, blogs for users, and forums as a free-for-all.
First of all, administration of each multi-site will be essentially independent from another with the exception of the user tables, because we will share accounts across the sites. The three tables you'll want to separate from the rest of your configuration are at least
- authmap
- sessions
- users
You might as why not share the role and users_roles, but in this example, a content editor role won't have any usefulness on the blogs subdomain, neither will a forum moderator have a point administering blogs.
As part of this, there will be three subdomains: www, blogs, and forums, which means our database names will be
- drupal_www
- drupal_blogs
- drupal_forums
- drupal_userdb
Your file directory structure will request primarily from www, meaning that will be the default configuration of your Drupal multi-site installation.
/root folder
- sites
- default (dir)
- settings.php
$db_url = 'mysql://user:password@localhost/drupal_www';
$db_prefix = array(
'default' => '',
'authmap' => 'drupal_userdb.',
'sessions' => 'drupal_userdb.',
'users' => 'drupal_userdb.'
);
$base_url = 'http://www.mysite.com';
- settings.php
- blogs.mysite.com (dir)
- settings.php
$db_url = 'mysql://user:password@localhost/drupal_blogs';
$db_prefix = array(
'default' => '',
'authmap' => 'drupal_userdb.',
'sessions' => 'drupal_userdb.',
'users' => 'drupal_userdb.'
);
$base_url = 'http://blogs.mysite.com';
- settings.php
- forums.mysite.com (dir)
- settings.php
$db_url = 'mysql://user:password@localhost/drupal_forums';
$db_prefix = array(
'default' => '',
'authmap' => 'drupal_userdb.',
'sessions' => 'drupal_userdb.',
'users' => 'drupal_userdb.'
);
$base_url = 'http://forums.mysite.com';
- settings.php
- default (dir)
So far to this point, it's a fairly standard installation of multi-site Drupal with sharing the tables, but it's hard to use multi-site in a local environment if you want to be able to test each of the subdomains, which will only respond to the domains set in the directory names.
Since you shouldn't check your settings file into version control, your local copy of the settings.php files will change the $base_url to something more local-ish.
$base_url = 'http://forums.mysite.local';Then update your /etc/hosts file to have some new entries:
127.0.0.1 www.mysite.local
127.0.0.1 blogs.mysite.local
127.0.0.1 forums.mysite.localThen make a symbolic link to each one of your multi-site directories so Drupal will be able to find the local domains and respond to them with the local domain settings.
/root folder
- sites
- default (dir)
- blogs.mysite.com (dir)
- blogs.mysite.local (symlink)
- forums.mysite.com (dir)
- forums.mysite.local (symlink)
Your symlinks and settings.php files won't be in version control because you ignored them (right?), so you should be able to easily develop from a local multi-site environment without having to setup a fancy MAMP-like package to manage your virtual, local domains.
Submitted by deekayen on Wed, 02/11/2009 - 11:25pm
deekayen's blog | Printer-friendly version
About the shared database user
Hello,
Before beginning, I just want to say "Congratulations" for this tuto. Indeed, i found it very useful and very detailled. But I have a question.
You said that the users, sessions and authmap tables have to be shared. But how do you shared these 3 tables when you install your first domain. I mean, you can't choose a specific DB for specific tables.
So, my question is: Do you move manually the 3 tables from the original DB to the "drupal_userdb" DB after the installation of your first site ?
Thanks a lot ;-)
Drupal multisite on 1200 domains
Can you see any problem with installing Drupal multisite on 1200 domains? The system would have one administrator writing the content for each site. Each site would be 5-20 pages with low traffic. I just wondered if Drupal could handle that.
What happens to the sequences table if you add a user?
I wish I saw the trick of 'users' => 'drupal_userdb.' for specifying a different database a few months ago. We went with putting many sites in to one database with table prefixes for the content and the shared_ prefix for the shared tables.
One thing I see above is that if the sequences table is not shared wouldn't you have problems when someone adds a user to the forum and gets id #2 then a user gets added to the blog and gets the same id? Or is there something that prevents this like some custom code or a mysql view?
Thanks for the great reference.
no sequences
Sequences isn't needed anymore in D6 because schema allows use of auto increment on tables.
Larger architectural overhaul
Going off this idea, we have created an architecture / implementation in which one drupal site reports to others (and visa versa) so we have a seting that has /courses/ as the root website and then other sites like /courses/art100/ as a site in the same "network" using the same codebase but with different content / settings / etc.
Here's some of the other tables we've centralized that would be good for creating "cross-network" like websites
'profile_values' => 'centraldb.', 'profile_fields' => 'centraldb.', 'role' => 'centraldb.', 'tinymce_settings' => 'centraldb.', 'tinymce_role' => 'centraldb.',
The tinymce things are specific to the tinymce project (dev one) but this plays into our standardized role names so that while someone might have different roles in different systems, the roles themselves are consistent across the systems. Profile values / fields are also good to add in so that you can carry your identity across your network without needing multiple profiles on different sites in the same grouping. We don't centralize sessions though I guess we could and I may look into that more but another reason this is a good architecture to go with is so that you can track users and keep tabs on them across your network (our courses site can set permissions for a user based on role globally across all sites w/ a very simple query since the uid in drupal is the same for example). If you centralized the watchdog you could also do monitoring across all your sites as well.
Bravo!
There are some performance
There are some performance implications with your sessions table. If you have many high traffic sites in your network then your sessions table can become quite large which means that the write queries that happen on every bootstrap become slower.
Of course the advantage of sharing your sessions table being that your users can login once across all sites (if they share the same root domain, if not then you can use multisite_login module).
Post new comment