Hi,

I'm working on a multi-site system based on Drupal. I first tried the prefixed database method and I read about multi-database possibilities but I thought pre-fixing or multi-database wasn't necessary and made any maintenance way more complicated.

So I tried doing multi-site this way:

- normal procedure with Apache vhosts + one folder in /sites for each domain, including its specific settings.php file
- one and only database with no specific prefixing on tables
- a vocabulary called "Site" with each of its terms representing a site
- in the settings.php file: forcing the name, theme + front_page variables for each domain
- the front_page variable is set for each site to taxonomy/term/x where x is the id of the term corresponding to the site, chosen from the "Site" vocabulary.

The expected result is a multi-site thing with each site having its own theme/blocks, name, content.

The real result I get is that it works like expected at the beginning but a few minutes later, I get white front pages on both all the domains, though the content is still accessible if I specify the taxonomy on the url manually.

I first thought it was incompatible with the cache system but disabling cache didn't fix it.

Is there something I did wrong? Is the way Drupal has been coded compatible with what I'm trying to do?

Can I hope doing multi-site with one database and with non pre-fixed tables?

Do you think Drupal future development regarding multi-site is in that spirit?

If not, should it be?

Thanks.

Comments

neural’s picture

I meant I get blank front pages on all the domains... except when I'm logged in, when I override the site_frontpage variable with a taxonomy path on each site's settings.php file.

Robardi56’s picture

I had the exact same need as you. My conclusion after researching, is that drupal wasn't build with the idea of several sites sharing same content. You will find many threads and pages about sharing same code, but not same content.
There is obviously a cache problem to start with.... you might get it over with different cache tables, I don't know and didn't wanted to venture there. This is from a non code point of view.... i'm sure drupal gurus could get this running.

I made the same test as you, and got weird results. My sites really felt unstable so I ended up restoring a database backup and installing another drupal copy for second site !!

I strongly think that drupal should allow several sites (each with its custom theme / blocks) to share same code and content.

This was with 4.7.4, I don't know about upcoming 5.0 though.

Brakkar

neural’s picture

Thanks brakkar.

Do you know what's the tables I need to share at minimum?

My first try had the following tables pre-fixed for each site:

- blocks
- cache
- menu
- system
- variable

And all the other tables are shared.

As I created a custom theme for each of my sites, I guess I don't need to have blocks and menu tables any longer for each site, unless I want to control availability (and not just display) of the blocks in the admin section for each site.

Should I try with pre-fixing just cache, system and variable? Has anyone tested this scheme?

It would be nice to have the point of view of drupal gurus and/or developers about "multi-site with all content/tables shared but different front-pages+themes".

Thanks.

cog.rusty’s picture

I can't say if your method is the future but it is very interesting.

The semi-shared database methods, assuming you get them to work, are very sensitive. Most multi-prefix setups have too complicated logic, they easily become unstable with the slightest mistake and they are very hard to change.

So, I am curious to know why exactly your method failed. Was what happened an expected behavior or is it a bug? I suspect that it is a bug and that your method was supposed to work. For what other reason would settings.php allow you to override the settings of a database's variables table for each specific site?

If you document a simple use case which can be verified, where you show that settings.php does not behave as it should and submit an issue for a bug then, who knows, it may become possible in the future.

For example, does it fail with two identical sites with different forced front pages? With different forced themes? Only when you force both?

neural’s picture

Good idea, I might post an issue linking here.

With different themes, no problem.

Even if I do both different theme + different front page it works.

But when I try assigning a taxonomy term as front page on one of the sites, then it screws.

Gman’s picture

First, do you have caching enabled and do you see the pages once, and then on reload or coming back to the page does it fail? Did you normal site work without those multisites? Just checking some options. If you don't have the mbstring extention in PHP, you might have similar problems. I sure did.

You are correct that the cache table should almost never be shared across subdomains. Many of the links for themes and menus are placed into the cache and if will mess up links across subdomains. Trying making separate tables for the caches?

My own tests showed that the CCK module does not work across subdomains and common content (shared nodes and related tables). The cached CCK nodes are only cached in the subsite it was created in, and none of the others. Also, other cached settings like TinyMCE settings and filters did not go across the shared content multisite.

Again, this is across sub-domains, and I believe that across main domain will act the same way. Maybe you could try a setup across simulated directories, instead of sub-domains.

----------
My Drupal/Tech Thoughts
vbDrupal Articles at Skejo.com

neural’s picture

The site works perfectly when I point every front page to /node, with cache-enabled or not.

When I used the configuration I described with overridden site_frontpage variables for each site. The site first loaded correctly and displayed the appropriate content, exactly as I had expected. But a few minutes later (maybe when the cache was renewed), it started showing a blank page on both of the sites.

I also noticed that it wrote the settings.php file overridden variables also in the database variable table.

Disabling cache didn't solve the issue.

cog.rusty’s picture

I just thought: What happens to the variables table when different users browse different sites? What is the front page, for example? And what is the theme? Hopeless. It's a race condition. Modules go all the time and ask for a variable from the table and it becomes a game of chance.

Maybe you could try your method with separate prefixed cache and variables, starting the variable tables as exact copies then leaving them alone to diverge?

Hmm... you might have to synchronize them from time to time whenever you set up something... Complicated.

neural’s picture

Yes, it gets quickly complicated when you start pre-fixing tables, that's why I'm trying to avoid this.

Any advice on that from Drupal developers would be welcome.

cog.rusty’s picture

True, yet, if the logic in my last comment is correct a shared variables table is completely out of the question.

Thousands of users browsing the different sites may cause the writing of different values in the variables table and their modules retrieve the last values written regardless of what site they are browsing.

Or, if the variables table is not updated by user activity, then only one site has the correct variables.

neural’s picture

What about System? Do you think I can keep it shared? Assuming I'm using the same modules for all the sites.

I guess cache will also need to be pre-fixed, unless it can handle multi-domain caching with different front pages. Depends if it identifies a static page with the url base + path or if it's only with the path.

cog.rusty’s picture

I don't see any problem with sharing the system table. It seems to contain static information about installed and enabled modules and nothing more. Except, if you disable a module in one site you disable it in all of them.

brenda003’s picture

I've read some no-nos about sharing the system table. And in an attempt to do it once, it reset everything each time I switched from site to site.

cog.rusty’s picture

I googled a bit and I only found one vague reference that "[another] person ran into problems with the [shared] system table". I guess there is only one way to know...

On the other hand, I can think of possible problems with separate system tables (allowing different modules enabled and different module update version info) in sites with shared content.

-----

*** Edit: I see now how a shared system table might cause problems: If you have some modules installed under /sites/onesite, then the other sites don't see these modules (and they shouldn't), so these modules should not be in their system table.

But still, with separate tables, one must be careful with updating shared modules (in /modules), since a module update on one site may change both shared and non-shared tables, while the new version info will be updated only on one site. The update will have to be run on the other sites too, to make changes to their non-shared tables and to update their version info. With any luck, a repeat-update of a module's shared tables will give some warnings and won't do any harm.

What is the safest choice may depend...

brenda003’s picture

I have two sites sharing content although I do have two databases. I have different front pages defined for each, as well as different content showing up dependent on their categories in various sections of the site. What does your settings.php file look like? I have the "main" site in the sites/default folder, and the "secondary" site in sites/othersite.com - in the settings.php file, I actually have to have each and every table I am sharing listed.


    $db_prefix = array(
      'default'   => '',
      'authmap'   => 'main.',
      'flexinode_data' => 'main.',
      'flexinode_field' => 'main.',
      'flexinode_type' => 'main.',
      'profile_fields' => 'main.',
      'profile_values' => 'main.',
      'role'      => 'main.',
      'sequences' => 'main.',
      'sessions'  => 'main.',
      'users'     => 'main.',
      'users_roles'     => 'main.',
      'role'      => 'main.',
      'node'      => 'main.',
      'node_access' => 'main.',
      'node_comment_statistics' => 'main.',
      'node_counter' => 'main.',
      'node_revisions' => 'main.',
      'event'     => 'main.',
      'profile_fields' => 'main.',
      'profile_values' => 'main.',
      'signup'    => 'main.',
      'signup_log' => 'main.',
      'term_data' => 'main.',
      'term_hierarchy' => 'main.',
      'term_node'  => 'main.',
      'term_relation' => 'main.',
      'term_synonym' => 'main.',
      'url_alias'  => 'main.',
      'vocabulary' => 'main.',
      'vocabulary_node_types' => 'main.',
      'view_argument' => 'main.',
      'view_exposed_filter' => 'main.',
      'view_filter' => 'main.',
      'view_sort' => 'main.',
      'view_tablefield' => 'main.',
      'view_view' => 'main.',
    );

Seems to work.

neural’s picture

I'll probably try with "system" and "variable" as prefixed tables and all the others will be common (shared).

Then I separate content for each site with taxonomy.

If it works, I guess it's the easiest way to do multi-site without too much complicated update and maintenance procedures.

Another advantage of sharing content and taxonomy through sites is the fact that you can easily make available some content on two sites. Mine talk about Apple, Mac and iPod stuff and sometimes some articles may be relevant to several sites.

You may also use taxonomy_hide with prefixed tables so as to not confuse readers with irrelevant taxonomy.

If I got something working fine, I'll post a case study and I'll also talk about the Drupal/Apache performance tests as these sites get considerable traffic.

I'm still interested in other experiences on multi-site with minimal prefixing and maximum shared tables, especially for "cache" and "system" tables, as it now looks obvious that the "variable" table mustn't be shared.

Also if anyone from the Drupal dev team can comment on the direction those who are doing multi-site should take, it would be welcome too.

Thanks everyone.

bottdev’s picture

I am trying to do something very similar to neural's situation of having a lot of shared content but having a unique theme for each site and managing the unique content through the theme/blocks, and taxonomy.

But I am having the same "white page" problem. Sometimes it is only on the front page and other times I get it on other pages.

I have searched but not found anywhere where a solution to this problem was explained. Has anyone conquered this problem? Can you please provide some guidance?

Thanks!!

stuartgoff’s picture

I'm sharing 4 sites and I have issues with adding new modules.

A little history. I am setting up 4 sites that share the majority of content but in cases where the content differs I modify the navigation. So I am NOT sharing System tables or Navigation tables. (http://drupal.org/node/70796) But I have my prefixes so that the shared tables have no prefix and the shared do have prefixes according to this article http://drupal.org/node/22267.

But my problem is that as I add new modules many add to the DB tables as the default of NOT shared. As you can see at the end of my code i have added to the list of shared tables for modules that I know I will be using. Everything I have read says that this is the way to setup for multisite, but it would be much easier to switch this to the 'default' is shared and those not shared would have the prefix. Does anyone have any ideas? Also, what can we look forward to for multisite in 5.0

Example:

$db_prefix = array(
	'default'   => 'dr_',
	'authmap' => '',
	'book' => '',
	'client' => '',
	'client_system' => '',
	'comments' => '',
	'files' => '',
	'file_revisions' => '',
	'filters' => '',
	'filter_formats' => '',
	'forum' => '',
	'locales_meta' => '',
	'locales_source' => '',
	'locales_target' => '',
	'node' => '',
	'node_access' => '',
	'node_comment_statistics' => '',
	'node_counter' => '',
	'node_revisions' => '',
	'permission' => '',
	'poll' => '',
	'poll_choices' => '',
	'poll_votes' => '',
	'profile_fields' => '',
	'profile_values' => '',
	'role' => '',
	'sessions' => '',
	'sequences' => '',
	'term_data' => '',
	'term_hierarchy' => '',
	'term_node' => '',
	'term_relation' => '',
	'term_synonym' => '',
	'users' => '',
	'users_roles' => '',
	'vocabulary' => '',
	'vocabulary_node_types' => '',
	//extra modules
	//browscap
	'browscap' => '',
	'browscap_statistics' => '',
	//click
	'clicks' => '',
	//event
	'event' => '',
	//event repeat
	'event_repeat' => '',
	'event_repeat_nodes' => '',
	'event_repeat_calendar_map' => '',
	//forms
	'forms' => '',
	'form_fields' => '',
	//gmap
	'gmap_user' => '',
	'location' => '',
	//gsitemap
	'gsitemap' => '',
	//nodewords 
	'nodewords' => '',
	//survey
	'survey' => '',
	'survey_responses' => '',
	'survey_fields' => '',
	//views
	'view_view' => '',
	'view_sort' => '',
	'view_argument' => '',
	'view_tablefield' => '',
	'view_filter' => '',
	'view_exposed_filter' => '',
);

Thanks,
Stu

cog.rusty’s picture

You ask: Is it better to
- make the shared tables the default and then list the separate tables, or
- make the separate tables the default and list the shared tables?

I have always found the first method more convenient for working out the logic. Why? To figure out which tables to unshare I start from the basic entities (node, user, category/term) which have numeric IDs and apply a simple rule.

"If I want separate users, then all modules (core or contributed) which contain uid (user id) anywhere must be separated."

User #15 in one site is not the same as user #15 in the other site. So, this uid must not be shared anywhere. Applying my rule, I may want to share the roles table, but the users_roles table (for assignment of roles to users) must be separate because it contains uids.

The opposite is not true. If I make the users table shared, it is not necessary to share any other tables containing uid. They may be separate. They are the same users, but they don't do the same things.

The same for nodes or any other basic entity with a numeric ID. If I started with separate as the default, I would not be able to apply my simple rule. Starting with shared tables, even a machine can sort them out with no questions asked.

stuartgoff’s picture

I agree w/ cogrusty and would prefer to make the 'shared tables the default and then list the separate(unique) tables'

But post - LOCK TABLES problem - post in http://drupal.org/node/22267 states that this can create problems. So... is someone running a Drupal site with my desired config and is this 'Locked Tables' issue fixed?

cog.rusty’s picture

Looking back at my phrase "even a machine can sort them out" I wonder whether a script is possible which would be aware of the relational constraits and Drupal's basic entities, would take a look at the tables of the modules you install and give you some basic choices, and would generate prefix arrays for you. That would make the initial question moot.

(No, I can't write this script and I suspect it would not be trivial to make it failsafe...)

Gman’s picture

My site, www.skejo.com is running this way, with the default pointing at the shared tables.

$db_prefix = array(
'default'  		=> '',
'access'		=> $db_name,
'accesslog'		=> $db_name,
'blocks'		=> $db_name,
'boxes'			=> $db_name,
'cache'			=> $db_name,
'menu'			=> $db_name,
'panels_area'		=> $db_name,
'panels_info'		=> $db_name,
'permission'		=> $db_name,
'poll'			=> $db_name,
'poll_choices'		=> $db_name,
'poll_votes'		=> $db_name,
'view_argument'		=> $db_name,
'view_exposed_filter'	=> $db_name,
'view_filter'		=> $db_name,
'view_sort'		=> $db_name,
'view_tablefield'	=> $db_name,
'view_view'		=> $db_name,
   );

Those are the distinct tables listed, with the default pointing at the rest. This is a priority for me so I can add new modules, without having to change any of the settings.php files.

It does work for me.

My setup is:

Version 4.7.3
Sites directory default
Url http://www.skejo.com
Database prefix
default vb_drupal_
access vb_drupal_
accesslog vb_drupal_
blocks vb_drupal_
boxes vb_drupal_
cache vb_drupal_
menu vb_drupal_
panels_area vb_drupal_
panels_info vb_drupal_
permission vb_drupal_
poll vb_drupal_
poll_choices vb_drupal_
poll_votes vb_drupal_
view_argument vb_drupal_
view_exposed_filter vb_drupal_
view_filter vb_drupal_
view_sort vb_drupal_
view_tablefield vb_drupal_
view_view vb_drupal_
user vb_drupal_
Web Server
Type Apache
Version 1.3.36
PHP Interface Module
PHP
Version 4.4.2
Magic Quotes GPC Off
Magic Quotes Runtime Off
Memory Limit
Register Globals Off
Safe Mode Off
Session Cache Limiter none
Session Save Handler user
Upload Max Filesize 20M
Extensions
CURL Support Enabled
GD Version bundled (2.0.28 compatible)
FreeType Support Enabled
XML Support Enabled
Zip Support Disabled
Zlib Support Enabled

Greg

----------
My Drupal/Tech Thoughts
vbDrupal Articles at Skejo.com

macm’s picture

Hi,

I found here the best discussion about multisite config.

Let me understand something

I went to my settings.php of mysite1

and change to
$db_url = 'mysql://username:password@localhost/databasename'; // here is ok and know config this line
$db_prefix = 'ps_'; and dont work

after I tried
$db_prefix = array(
'default' => 'ps_',);

and dont work too

where ps_ is my primary prefix

So It is missing something.

After this I listed all tables in phpmyadmin and create

$db_prefix = array(
'default' => '',
'access' => 'ps_',
'accesslog' => 'ps_',
'aggregator_category' => 'ps_',
'aggregator_category_feed' => 'ps_',
'aggregator_category_item' => 'ps_',
'aggregator_feed' => 'ps_',
'aggregator_item' => 'ps_',
'authmap' => 'ps_',
'blocks' => 'ps_',
'book' => 'ps_',
'boxes' => 'ps_',
'cache' => 'ps_',
'client' => 'ps_',
'client_system' => 'ps_',
'comments' => 'ps_',
'contact' => 'ps_',
'files' => 'ps_',
'file_revisions' => 'ps_',
'filters' => 'ps_',
'filter_formats' => 'ps_',
'flood' => 'ps_',
'forum' => 'ps_',
'history' => 'ps_',
'locales_meta' => 'ps_',
'locales_source' => 'ps_',
'locales_target' => 'ps_',
'menu' => 'ps_',
'node' => 'ps_',
'node_access' => 'ps_',
'node_comment_statistics' => 'ps_',
'node_counter' => 'ps_',
'node_revisions' => 'ps_',
'permission' => 'ps_',
'poll' => 'ps_',
'poll_choices' => 'ps_',
'poll_votes' => 'ps_',
'profile_fields' => 'ps_',
'profile_values' => 'ps_',
'role' => 'ps_',
'search_dataset' => 'ps_',
'search_index' => 'ps_',
'search_total' => 'ps_',
'sequences' => 'ps_',
'sessions' => 'ps_',
'system' => 'ps_',
'term_data' => 'ps_',
'term_hierarchy' => 'ps_',
'term_node' => 'ps_',
'term_relation' => 'ps_',
'term_synonym' => 'ps_',
'url_alias' => 'ps_',
'users' => 'ps_',
'users_roles' => 'ps_',
'variable' => 'ps_',
'vocabulary' => 'ps_',
'vocabulary_node_types' => 'ps_',
'watchdog' => 'ps_',
);

and ont work again

So What is wrong? It is a new instalattion and I read instruction to install multisites and I am failing in something.

I have some cck tables in mysite1 that dont exist in mysite2 neither mysite3 (and vice versa) I think it is not a problem.

Best Regards

Mario

cog.rusty’s picture

What did you see when you listed all tables in phpmyadmin? Did some tables have a prefix or not?

Also, what are you trying to do? What do you want to be different in your sites and what do you want to be the same?

macm’s picture

Yes I think it is the problem. My database dont have tables with prefixes.

How is the best way to create prefixes? I read it is manually! :(

I need share users and profiles only. I read your post CogRusty by the way is excelent!

cog.rusty’s picture

You can make a different copy of the database.mysql file for each site, open it with a text editor and add the table prefix before the table names in every *non-shared* CREATE TABLE and every INSERT statement. For example, change "CREATE TABLE node" to "CREATE TABLE ps_node" if ps_ is only for one site.

The *shared* tables should be only in one copy of the database.mysql file, so that they are created only one time. Delete them from the others.

Then use each copy for creating the database tables for each site.

macm’s picture

Yes you are right, thanks a lot.

Let me ask one more thing.

I have myccktype1

How Can I filter it?

For example:

User of site1 post myccktype1
User of site2 post myccktype1

How can I create a views to site1 and other to site2?

It is mean that myccktype1 post in site1 can be visible only in site1 and never in site2 (viceversa).

Sorry my mistake !! My brain is breaking. In case above I was admiting share all tables. Sorry and thanks by answer.

cog.rusty’s picture

It was a difficult question anyway.

A short answer for having same content types and different views is to separate at least the "node_term" tables. But maybe this is not enough and you need to separate other vocabulary and term related tables as well, especially if there are "required" vocabularies for your node types. Also you would have to check how your other contributed modules (such as views and your access control modules) use the tables.

Separate tables are usually the safest way. Shared tables are economic but they need much thought, testing, more though and more testing for each additional module you install.

cog.rusty’s picture

Since my previous argument, I have realized that there is also a practical problem with the tables which the additional contributed modules will create and then use. If settings.php is left unmodified they will follow the site's "default" for their own tables, and shared tables are more likely to cause errors than separate ones (for example if they use uids but users are separate and the default setting is "shared").

So, *before* installing a new module, one would have to take a look at its ".install" file, decide about the tables it creates and add the right entries in the settings.php file.

macm’s picture

Ok. thanks a lot

I will take care with new modules.

At this moment I am planning my website carefully but you know in the middle of the project we can decide add more one module and more one...

So best pratice is decide all modules first.

CogRusty thanks for help me.

Now It is late here, I will study about new modules tomorrow.

marcoBauli’s picture

Howdy,

i profit of this interesting thread and of the expertise of neural, coughrusty and others to scratch my own itch:

my site is an aggregator with something like 30 main taxonomies, and i'd like to keep a unique code and layout, but have different subdomains for each term (ex: cats.mysite.com, penguins.mysite.com, ...) pointing to their respective front page (the term node).

Basically everything remains the same across all sites (layout, users, taxonomies, ..), only thing i need to have separated blocks tables to show different blocks on each site.

My main site is at /sites/mysite.com, and secondary sites are at /sites/cats.mysite.com, /sites/penguins.mysite.com etc..

I tryed all the ways:

  1. prefix only separated tables:
    'default' => '',
    'blocks' => 'sub_',
  2. prefix the default ones and leave empty the shared ones as adviced at 22267:
    'default' => 'sub_',
    'block' => '',
  3. give all my tables a prefix 'main_' and go through steps 1 and 2

Nothing:
every time i change (add, remove, sort) a block in www.mysite.com, the change reflects also in subsite.mysite.com.... <:|

really don't know where to bump my head here..

i am actually sharing these tables:
`blocks`
`boxes`
`caches`

Am i wrong? Shall i share something else (system, variables,..)?

Please, any hand extremely apreciated, thank you lot in advance!




---------------- Edit: SOLVED! ------------------------

aha, seems the issue was with the name of the /site folders not catching up with the subsites:

renaming them to /sites/cats.mysite.com, /sites/penguins.mysite.com (*not* mysite.com.cats, mysite.com.penguins ) solved the problem!

Also seems that just prefixing separated tables only is working fine:
'default' => 'main_',
'blocks' => 'sub_',

so the issue at 22267 seems to be fixed now.

Gman’s picture

Great to hear. I thought it was fixed, but I had not done the exhaustive testing that you just did. I was working on a wing and prayer that it wouldn't crash. Now I am more confident.

Thanks

----------
My Drupal/Tech Thoughts
vbDrupal Articles at Skejo.com

stuartgoff’s picture

I now have two different sets of site with multi site set. The first setup based on directions in http://drupal.org/node/22267 and the second using the setting I questioned earlier in this thread. The second as setting the prefix on the non_shared DB. Both work just fine.

I will empasize that you must still do some research on installing new modules. Read the MySQL files. But one of the reasons that my preference was to prefix the non_shared DB was that the default should be shared hence any new modules should be default=shared.

Stuart

najibx’s picture

it's been 5 months now since this was posted.

after all the testing and comment from others, I wonder what's the best practice to achieve this (multisite with shared content and minimal prefixing.) + allow content addition from respective sites (based on permission).

another comparison using Views/OG multisite: creating/managing content for multiple sites from a single interface

or Managing multisite content from a single Drupal instance

there are just more out there ....

its difficult when information are all over the place, but yet could not find the final answer and I get lost...iskhh iskhh ....

-najibx-